• Advertisement
Sign in to follow this  

only one function as friend

This topic is 3315 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

Advertisement
Quote:
Original post by alnite
Like this?

http://www.cprogramming.com/tutorial/friends.html


I had something else in mind. In those examples one function is given access to the entire class, what I want to do is give one class access to only one function of another class.

So


class A
{
public:

void foo( b.boo() );

private:

B b;

};

class B
{
private:

void boo();
};

Share this post


Link to post
Share on other sites
AFAIK it isn't possible to restrict the export to a single function by using the friend keyword. The only way I see is to export an intermediate object especially for accessing the funtion of interest. However, I doubt that it is worth the effort (but perhaps it is; the OP hasn't told about the reasoning of wanting to do so).

Share this post


Link to post
Share on other sites
This could do:

int function1(void);

class a{
public:
class{
private:
friend int function1(void);
int operator(int c);
}function2;
private:
int function3(void);
};

int function1(void){
static a instance;
return instance.function2(77);
}



Share this post


Link to post
Share on other sites
Quote:
Original post by VanillaSnake21
Anyways it looks like theres no clean way of doing this. I'll just declare the whole class as a friend and save myself the trouble of sifting through spaghetti code later on. Thanks for the help )
Why does this class need to access a function that isn't part of the other class' public interface? In general, that sounds like a problem with your design.

Share this post


Link to post
Share on other sites
Every once and a while I have something like this happen. I've had a couple methods that only one other class should call.
I usually just make the entire class a friend. If a class knows enough about another class to be friends with one of its methods, then it knows enough to be a friend with the entire class.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Why does this class need to access a function that isn't part of the other class' public interface? In general, that sounds like a problem with your design.


One class is called Engine the other class is called Time.
Time class can be owned by any of the Engine subsystems and what it does is it keeps the time since the engine was started (so I can sync all the subsystems). Time class has a functino CallOnCreation(), that should be called in the Engines's constructor. But I don't want that function to be called by any other subsystem (since it will offset the time) So I made the function private and made the Engine class a friend of time class. It's not really a big deal, I'm just trying to be overprotective. BTW If anyone has any suggestions on how I can improve this design let me know.

To be more precise here's a simplified example,


class Time
{
public:
long GetTimeSinceCreation() { return timeGetTime() - m_CreationTime; }
private:
void CallOnCreation() { m_CreationTime = timeGetTime(); }

static long m_CreationTime;

friend class Engine;
};

Engine
{
public:
Engine() { m_EngineTime.CallOnCreation(); }

private:
Time m_EngineTime;
Subsystem WindowManager;
Subsystem Input;
// more subsystems
};

class WindowManager
{
private:
Time m_EngineTime;
};

class Input
{
private:
Time m_EngineTime;
};


Share this post


Link to post
Share on other sites
What you have here is basically a monostate, and monostates are basically globals hiding under another name. That is not to say they are always a bad thing, but they should be treated with care.

In your particular case, why are all the subsystems running on global time? What happens if you need to pause the game at a menu, but animate menu transitions? Or if you want to perform slow-motion/bullet-time effects? Things like these would be much easier if subsystems could be allocated different timers...

Share this post


Link to post
Share on other sites
The hardcore OOP answer: A class has two kinds of stuff, public stuff and private stuff. The purpose of keeping the private stuff private is to hide implementation details and (more importantly) to maintain class invariants. Allowing exactly one class access to a particular member means that you're of two minds about whether that member is safe to expose. If it isn't safe to expose, expose a public function that makes it safe. If it is safe to expose, then it's safe to expose to everybody, even if most other people won't want to use it.

BTW, the above reasoning only applies if you're trying to make excuses for a language which does not support closures, partial application, or anonymous inner classes, such as C++.

In general, though, classes are not always self-documenting WRT what other classes they play with, and they're almost never self-documenting WRT what classes play with them. It sounds like you might be trying to do that.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
What you have here is basically a monostate, and monostates are basically globals hiding under another name. That is not to say they are always a bad thing, but they should be treated with care.

In your particular case, why are all the subsystems running on global time? What happens if you need to pause the game at a menu, but animate menu transitions? Or if you want to perform slow-motion/bullet-time effects? Things like these would be much easier if subsystems could be allocated different timers...


I'm not really sure what monostates are but a quick google search said something about them beaning similar to singletons, which I guess is what I'm trying to achieve.
I don't see how global time would present a problem. The Engine time that I'm using here has nothing to do with game time. This time is only used to make sure that for example if one subsystem requests something from the engine and another subsystem requests something else, the engine will be able to prioritize the requests based on the Engine time at which they were issued. I also use this time to completely halt all the engine activities related to the game (in case of an error). I have not yet gotten to animation in this little framework so I haven't yet thought about how I'm going to implement game time, but it's definitely going to be a seperate entity.

@Sneftel
I had to reread your post twice and use Wikipedia in an attempt to understand it [props :)]. From what I managed to understand you're saying that what I'm doign is not good. But as for the reason, you lost me at invariant [wow]

Share this post


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

  • Advertisement