This is a how C++ works question.
I’ve been looking into the friend modifier and found an example of a static friend method here.
But now I’m having trouble understanding why certain things were done to make it work.
I’m also curious of what practical application this could be used for? When would you want to use static friend? Should this be avoided?
Here’s the code with comments added to point out parts I’m confused about.
#include <iostream>
class A; //1. why declare class A here and define it below?
class B
{
public:
B();
~B();
static void SetAiPrivate(int value); //Makes SetAiPrivate static
static A *pa; //static instance of class A for class B's static
//methods to use
};
class A
{
friend void B::SetAiPrivate(int); //Gives Class B's SetAiPrivate method access
//to A's private variables
public:
A(){iPrivate = 0;}
~A(){}
void PrintData(){ std::cout << "iPrivate = "<< iPrivate<<"\n";}
private:
int iPrivate;
};
A *B::pa;//2. Why is this needed?
// If commented out it causes an external linking error.
B::B()
{
pa = new A;
}
B::~B()
{
delete pa;
}
void B::SetAiPrivate(int value)
{
pa->iPrivate = value;
}
int main()
{
B b; //3. Is this necessary? Doesn't C++ automatically initiate static
// member variables when a class is referenced
B::SetAiPrivate(7);
B::pa->PrintData();
return 0;
}
Let’s look at the code first:
That’s a forward declaration.
Bhas a member of typeA*, soAmust be declared beforehand.Static data members are only declared inside the class definition. That’s the definition and it’s required by the standard to be present in a single translation unit.
Not necessary. Unless of course the
staticmethods inBdepend on the run of the constructor. And if they do, it’s a bad design.Onto the
friendquestion. Usually, having friends breaks encapsulation, be them only members or a whole class. This is no different. It just tells the compiler thatA::iPrivateis directly accessible fromB::SetAiPrivate.This looks wrong to me, as you’d probably want to be able to set
A‘s member directly fromA, not fromB.