Jexah
Jexah

Reputation: 183

What is the difference between using the friend keyword, and using a member function to modify private variables inside of a class?

As the question asks...

What is the difference between:

class MyClass
{
public:
    MyClass(){
        m_a = 0;
    }
private:
    int m_a;
    friend void set_a(MyClass &a);
};


void set_a(MyClass &a)
{
    std::cout << a.m_a << std::endl;
    a.m_a = 500;
    std::cout << a.m_a << std::endl;
}



int main(void) {
    MyClass my_class_instance;
    set_a(my_class_instance);

    system("pause");
}

and:

class MyClass
{
public:
    MyClass(){
        m_a = 0;
    }
    void set_a(){
        std::cout << this->m_a << std::endl;
        this->m_a = 500;
        std::cout << this->m_a << std::endl;
    }
private:
    int m_a;
};



int main(void) {
    MyClass my_class_instance;
    my_class_instance.set_a();

    system("pause");
}

Is it simply the preferred structure of the function, or are there real, measurable differences? From what I can tell, both functions achieve the same results in all circumstances, except if you had multiple overloads for the first example, that took different types of objects.

Upvotes: 0

Views: 1044

Answers (3)

Manu343726
Manu343726

Reputation: 14174

As the C++ FAQ says: Use a member when you can, and a friend when you have to.

There are situations where making friend a free function is preferable, most situations related to the fact that the first parameter of a member function is always of that class (Its the hidden *this parameter).

One example is arithmetic operators overloading:
Suppose you write a complex class which represents complex numbers. Using a member operator+() you could write expressions like complex + float, but not float + complex. But you could do it with the free form of the operator+:

class complex
{
    ...
    friend complex operator+( float f , complex c );
};

Upvotes: 4

Massa
Massa

Reputation: 8972

Many people defend that making accessor methods, you can in a later stage of development put barriers to the incorrect access to the member variables (or even change the member variables totally) without breaking your (correct) clients.

One classical case is of a

class ComplexNumber {
  double real, imaginary;
public:
  double re() { return re; }
  double setRe(double v) { return re = v; }
// and so on ...
};

one day you discover, in some maintenance, that you need the polar coordinates for that number, so you add the methods

  double rho() { /* calculate rho */ }
  double theta() { /* calculate theta */ }
  double setRho(double v) { /* calculate real, imaginary, based on the new rho */ }

and so on.

Later yet, you discover that the users of the class use far more often polar than Cartesian coordinates for complex numbers, and that the conversions have been the bottleneck of a performance problem, so you ditch real and imaginary and store rho and theta, and change the getter and setter methods for the new -- more efficient -- storage for rho, theta, re, im, and so on. All the clients of your class will recompile without problems, because you changed your implementation but kept your interfaces stable.

Upvotes: 0

Christian Hackl
Christian Hackl

Reputation: 27538

This whole question comes down to "Why would I use friends in C++?". The answer is that when used properly, friends enhance encapsulation. This is an FAQ:

Do friends violate encapsulation?

Your example is too short and too abstract, of course. Some better, real life examples I could think of from the top of my head involve iterators. You may have many iterator objects referring to only one container object, and you may want the iterator to be able to access private member variables of the container. At the same time, you don't want the container to expose those variables to the rest of the world.

Such a design could be perfectly implemented with the friend feature.

Upvotes: 2

Related Questions