Reputation: 4459
Is there some way to initialize(?) member variable c of type C in the first part of the below example? Or must I use the new() method shown in the second part of the example?
Class B takes class A as an injected dependency. So does class C. Class B is additionally composed of class C.
How do I get the injected A to B's member C?
Part 1
class A { // ...; };
class C {
public:
C(A &a) : a(a) {} // constructor
};
// Does not work as is. Want to make compiler manage C lifetime.
class B {
public:
B(A &a); // constructor
C c(a); // member variable
};
// constructor
B::B(A &a) : a(a) {
}
Part 2
// Works, but requires programmer to manage C's lifetime.
class B {
public:
B(A &a); // constructor
C *c; // member variable
};
// constructor
B::B(A &a) : a(a) {
c = new C(a);
}
Several good answers below! My apologies for the confusing example. I have up-voted all of the good answers and questions. Unfortunately I can only mark one answer as the accepted answer, so I am choosing the first one which gave me the "ah-ha" moment in which I saw the solution to my real problem, which was more complex than my lame example here.
Upvotes: 0
Views: 3917
Reputation: 42838
The following:
C(A &a) : a(a) {}
will not compile since a
(the first a
in the initialization list) is not a member variable of C
.
Same applies to the constructor of B
.
Upvotes: 1
Reputation: 61910
You almost have it:
class B {
public:
B(A &a);
C c(a); //see note 1
};
B::B(A &a) : a(a) { //see note 2
}
There are two problems with C c(a);
here:
a
is not in scope. a
only exists within the scope of the constructor, so c
needs to be initialized from there.C c = value;
) or braces (C c{value};
) when initializing an NSDMI.You've almost got this right:
B::B(A &a) : a(a)
You're trying to initialize a data member called a
with the argument given to the constructor. You actually want to initialize c
like this, not a non-existent a
:
B::B(A &a) : c(a)
The lifetime of c
will be that of the instance of the B
class. Using dynamic memory management is certainly not necessary.
Upvotes: 3
Reputation: 1
"How do I get the injected A to B's member C?"
You can do so using B
's constructor member initializer list
class B {
public:
B(A &a) : c(a) {
// ^^^^
}
C c; // <<< It's not possible to initialize members in their
// declaration.
};
Upvotes: 1
Reputation: 9609
Member variables are initialized in constructor's initialization list (before body) so you need to do that:
B::B(A &a)
: c(a) // Calls constructor C(a) on member c
{}
Upvotes: 3