Mustafa
Mustafa

Reputation: 263

Using constructor of Friend Class

I have two classes A and B. A has declared B as a friend. In B I would like to instantiate A in method func() (i.e I am trying to instantiate A outside of the constructor of B). To my suprise this seems to be not allowed in C++. This is the code:

class A {
public:
        friend class B;
        A(int x, int y) {
                x_ = x;
                y_ = y;
        }
protected:
        int x_, y_;
};

class B {
public: 
        B (int z) {
                z_ = z;
        }

        void func () {
                a (3,4);
        }
protected:
        A a;
        int z_
};

I get the following errors:

friendConstructor.cpp: In constructor ‘B::B(int)’:
friendConstructor.cpp:14:12: error: no matching function for call to ‘A::A()’
friendConstructor.cpp:14:12: note: candidates are:
friendConstructor.cpp:4:2: note: A::A(int, int)
friendConstructor.cpp:4:2: note:   candidate expects 2 arguments, 0 provided
friendConstructor.cpp:1:7: note: A::A(const A&)
friendConstructor.cpp:1:7: note:   candidate expects 1 argument, 0 provided
friendConstructor.cpp: In member function ‘void B::func()’:
friendConstructor.cpp:19:9: error: no match for call to ‘(A) (int, int)’

I have a situation where I can't instansiate class A in class B's constructor. I have to wait for something to happen before I instansiate class A. If what I am trying to do is impossible in C++. Can you suggest an alternative?

Upvotes: 0

Views: 1929

Answers (4)

Matthew Mcveigh
Matthew Mcveigh

Reputation: 5685

You need to initialize a yourself as A doesn't contain a default constructor

class B {
public: 
        B (int z) : a(3,4) {
                z_ = z;
        }
protected:
        A a;
        int z_;
};

Upvotes: 1

Brian Gradin
Brian Gradin

Reputation: 2275

A doesn't have a default constructor. Since there is an instance of A in every B, the default constructor of B calls the default constructor of A, which doesn't exist.

Concerning what you are trying to do: as far as I'm aware, member variables should be instantiated as soon as the class instance is created. Think about it this way - what if you had a different method in B, let's call it func2(), which accesses a. Should we trust whoever uses your class to simply not use func2 until they've called func? No - that's not a safe programming practice. So basically, you should make sure that member variables are instantiated in the constructors.

You may be able to get around this, as @benjymous has pointed out, by using a pointer, or as @kfsone and @dornhege have pointed out, by simply assigning to a a new A instance (a = A(3, 4)). But again, I would suggest that it's generally preferable to make sure that member variables are instantiated for the lifetime of the class instance.

Upvotes: 0

kfsone
kfsone

Reputation: 24269

In func, a is a member variable, so it's instance was initialized (default constructed since you didn't specify how you wanted it initializing) when your instance of B was constructed. It has to be - it's a part of B.

What you are actually doing is calling overloaded A::operator(). The "a(3,4)" syntax only means "construct with these arguments" in a declaration or an initializer list of a constructor.

Your solutions are to add a member function to A to allow you to assign variables or construct a temporary and use assignment.

 a = A(3,4);

Upvotes: 2

dornhege
dornhege

Reputation: 1500

As the error says, you are making a function call, you probably want something like:

 a = A(3,4);

Upvotes: 0

Related Questions