Jump to content
  • Advertisement
Sign in to follow this  
FunLogic

Use of 'friend'

This topic is 4087 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have both a script and a script_manager class. The manager is responsible for updating an array of script instances that it holds in a std::list<>. Pretty straight forward, but the update member in the script class is private (and I'd like it to stay that way). In order to let the script_manager call script::update(), I've made the script_manager class a friend of the script class - is this justified or am I covering up for a bad design decision?

Share this post


Link to post
Share on other sites
Advertisement
You are covering up for a bad design decision. The Script and ScriptManager are too coupled, you should make it so the Script does not depend on the existence of the ScriptManager to work correctly—i.e. describe what a script is, and how it should be used, without making references to (or assuming the existence of) a manager for scripts— and only then introduce the ScriptManager.

Share this post


Link to post
Share on other sites
Granting friendship to functions is an acceptable usage, usually. Granting friendship to entire classes might occasionally be justified, but usually means you're covering up for bad or lazy design (and in this case, definitely seems to mean that).

Share this post


Link to post
Share on other sites
So ideally Script::Update() should be public and function correctly regardless of whether my ScriptManager calls it or not. In other words Main() could make a call to it?

The use of a ScriptManager should just make performing the same task on many Scripts easier.

i.e.

pManager->Update();

as opposed to...

pScript1->Update();
pScript2->Update();
pScript3->Update();

Share this post


Link to post
Share on other sites
Essentially, yes. Eventually you may come to realize that ScriptManager serves no useful purpose and can be removed. That's what happened to all of my manager classes over the years as I realized they were mostly crutches for not wanting to think about the problem.

The only thing I have left is a couple caches for doing LRU management of resources and such.

Share this post


Link to post
Share on other sites
Quote:
Original post by FunLogic
The use of a ScriptManager should just make performing the same task on many Scripts easier.


If that is all a manager does, I would possibly drop the use of a manager class altogether, and use a free-standing function instead:

template <typename It>
void UpdateScripts(It start, It end)
{
struct
{
void operator() (Script* s) { s->Update(); }
}
Updater;

std::for_each(start,end,Updater);
}

// Usage example:
std::vector<Script*> monsterScripts;
UpdateScripts(monsterScripts.begin(), monsterScripts.end());



Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
If that is all a manager does, I would possibly drop the use of a manager class altogether, and use a free-standing function instead:

*** Source Snippet Removed ***


Not to derail the thread, but what would you do in C# or Java? Create a class with a single public static function? This is one of the habits I'm trying to break in my own projects currently. Manager classes that support adding/removing items and delegating function calls. Glorified containers basically.

Share this post


Link to post
Share on other sites
Quote:

Not to derail the thread, but what would you do in C# or Java? Create a class with a single public static function?

Yes.

Chances are, though, that you don't need to update all the scripts in too many places, and such a utility method could just be a member of the class doing the update... It's sort of iffy whether or not you'd even need a separate method for it, since the iteration syntax in C# (at least) is a much more compact

foreach(Script script in listOfScripts)
script.Update();

in this simple example. Of course if more work is involved, that changes things.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!