Alex Rivera | Logout

Allowing a "friend" class to access only some private members

Asked 2013-04-17T08:50:30.267
44

Suppose I have three C++ classes FooA, FooB and FooC.

FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.

So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.

And I assume it will be nice if the following syntax is possible:

class FooA
{
private friend class FooB:
    void Hello();
    void Hello2();
private:
    void Hello3();
    int m_iData;
};

class FooB
{
    void fun()
    {
        FooA objA;
        objA.Hello()  // right
        objA.Hello2() // right
        objA.Hello3() // compile error
        ojbA.m_iData = 0; // compile error
    }
};

class FooC
{
    void fun()
    {
        FooA objA;
        objA.Hello()  // compile error
        objA.Hello2() // compile error
        objA.Hello3() // compile error
        ojbA.m_iData = 0; // compile error
    }
};
Edit
Report

1 Answer

1

No, and this is not really a limitation. To my mind, the limitation is that friend — a blunt weapon for hacking around design flaws — exists in the first place.

Your class FooA has no business knowing about FooB and FooC and "which one should be able to use it". It should have a public interface, and not care who can use it. That's the point of the interface! Calling functions within that interface should always leave the FooA in a nice, safe, happy, consistent state.

And if your concern is that you might accidentally use the FooA interface from somewhere you didn't mean to, well, simply don't do that; C++ is not a language suited to protecting against these kinds of user errors. Your test coverage should suffice in this case.

Strictly speaking, I'm sure you can obtain the functionality you're after with some ghastly complicated "design pattern" but, honestly, I wouldn't bother.

If this is a problem for the semantics of your program's design, then I politely suggest that your design has a flaw.

answered 2013-04-17T08:55:21.003

Your Answer