Reputation: 2755
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;
}
Upvotes: 1
Views: 1510
Reputation: 21351
1 why declare class A here and define it below?
You need to forward declare A if it is defined after class B as class B contains a pointer to an instance of A. Had you defined class A before class B this would not be needed
2 Why is this needed?
Static members must be initialised somewhere outside of the class definition
3 Is this necessary? Doesn't C++ automatically initiate static member variables when a class is referenced
AFAIK know this would not be needed for the very reasons that you mention
Upvotes: 1
Reputation: 258618
Let's look at the code first:
class A; //1. why declare class A here and define it below?
That's a forward declaration. B
has a member of type A*
, so A
must be declared beforehand.
A *B::pa;//2. Why is this needed?
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.
B b; //3. Is this necessary? Doesn't C++ automatically initiate static // member variables when a class is referenced
Not necessary. Unless of course the static
methods in B
depend on the run of the constructor. And if they do, it's a bad design.
Onto the friend
question. Usually, having friends breaks encapsulation, be them only members or a whole class. This is no different. It just tells the compiler that A::iPrivate
is directly accessible from B::SetAiPrivate
.
This looks wrong to me, as you'd probably want to be able to set A
's member directly from A
, not from B
.
Upvotes: 1