When should you use 'friend' in C++?

前端 未结 30 2024
孤街浪徒
孤街浪徒 2020-11-22 10:12

I have been reading through the C++ FAQ and was curious about the friend declaration. I personally have never used it, however I am interested in exploring the language.

30条回答
  •  独厮守ぢ
    2020-11-22 10:49

    You have to be very careful about when/where you use the friend keyword, and, like you, I have used it very rarely. Below are some notes on using friend and the alternatives.

    Let's say you want to compare two objects to see if they're equal. You could either:

    • Use accessor methods to do the comparison (check every ivar and determine equality).
    • Or, you could access all the members directly by making them public.

    The problem with the first option, is that that could be a LOT of accessors, which is (slightly) slower than direct variable access, harder to read, and cumbersome. The problem with the second approach is that you completely break encapsulation.

    What would be nice, is if we could define an external function which could still get access to the private members of a class. We can do this with the friend keyword:

    class Beer {
    public:
        friend bool equal(Beer a, Beer b);
    private:
        // ...
    };
    

    The method equal(Beer, Beer) now has direct access to a and b's private members (which may be char *brand, float percentAlcohol, etc. This is a rather contrived example, you would sooner apply friend to an overloaded == operator, but we'll get to that.

    A few things to note:

    • A friend is NOT a member function of the class
    • It is an ordinary function with special access to the private members of the class
    • Don't replace all accessors and mutators with friends (you may as well make everything public!)
    • Friendship isn't reciprocal
    • Friendship isn't transitive
    • Friendship isn't inherited
    • Or, as the C++ FAQ explains: "Just because I grant you friendship access to me doesn't automatically grant your kids access to me, doesn't automatically grant your friends access to me, and doesn't automatically grant me access to you."

    I only really use friends when it's much harder to do it the other way. As another example, many vector maths functions are often created as friends due to the interoperability of Mat2x2, Mat3x3, Mat4x4, Vec2, Vec3, Vec4, etc. And it's just so much easier to be friends, rather than have to use accessors everywhere. As pointed out, friend is often useful when applied to the << (really handy for debugging), >> and maybe the == operator, but can also be used for something like this:

    class Birds {
    public:
        friend Birds operator +(Birds, Birds);
    private:
        int numberInFlock;
    };
    
    
    Birds operator +(Birds b1, Birds b2) {
        Birds temp;
        temp.numberInFlock = b1.numberInFlock + b2.numberInFlock;
        return temp;
    }
    

    As I say, I don't use friend very often at all, but every now and then it's just what you need. Hope this helps!

提交回复
热议问题