Dan
Dan

Reputation: 2755

C++ Static Friend Method Example (Need Clarification)

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

Answers (2)

mathematician1975
mathematician1975

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

Luchian Grigore
Luchian Grigore

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

Related Questions