I am attempting to write two classes A
and B
where B
contains an instance of class A
. In practice, A
contains some large data. In this toy example, let's assume they are as follow:
class A{
public:
int a;
A(){}
A(const A& ac){
cout <<"copy constructor for A" << endl;
a = ac.a;
}
virtual ~A(){}
A& operator=(const A& that){
cout <<"operator = for A" << endl;
a = that.a;
return *this;
}
};
class B{
private:
A ba;
public:
B(){ a = A(); }
B(A& a){
cout << "Using default constructor" << endl;
ba = a;
}
B(const B& copy){
cout<<"copy"<< endl; ba = copy.ba;
}
B& operator=( const B& that){
cout<<"invoking operator = "<< k<< endl;
ba = that.ba;
return *this;
}
virtual ~B(){}
A& getA(){ return ba; }
void printAadrr(){
cout << &ba <<" "<< ba.a<< endl;
}
};
The problem with this is that when initializing B
using B::B(A& a)
, the argument is copied into the instance ba
in B
. It might be inefficient if a
is large.
I thought of another approach where instead of
class B{
private:
A ba;
....
I could do
class B{
private:
A* ba;
public:
B(){
ba = new A(); //but we have to free memory in destructor if we call default constructor
}
B(A& a){
cout << "Using default constructor" << endl;
ba = &a;
}
But this design choice has its own issue where if I make B
by default constructor, I need to free the memory allocated for ba
later on in the destructor.
Is there a convenient way to pass the "reference" of the object A
(created outside of B
) into B
in the constructor if we use B::B(A& a)
and create an empty, default A
object if we use B::B()? I tried
B::B(A& a){
&ba = &a;
}
but it gives "lvalue has to be on the left of assignment" error.
Any advice is appreciated. Sorry for the overly long post.
Define a constructor using move semantics as follows:
B::B( A && a )
: ba( std::move( a ) )
{}
Now you can transfer an instance into the object.
A a;
B b( std::move( a ) );
// `b` stores content of `a`, and local `a` is no longer valid.
You can still construct with the copy constructor if you want.
A a;
B b( a );
// `b` stores a copy of `a`, and local `a` is still valid.