Reputation: 8585
I have a question about the behavior of default copy constructor. For example, a class like this:
class A{
public:
A(){}
A(const A& a){}
~A(){}
void foo(){}
};
class B:public A{
public:
B(){}
B(const B& b){}
B& operator=(const B& b){return *this;}
~B(){}
virtual void foo(){}
};
class C:public B{
public:
C(){}
C& operator=(const C& c){a_=c.a_; return *this;}
~C(){}
void foo(){}
protected:
A a_;
};
if I will create a new object of class C like:
C* c1 = new C();
the steps would be:
if I will initialize a new object of class C like:
C c2(*c1);
it will invoke the default copy construcor of C. As far as I know, the steps would be:
How the default copy constructor behaves? What rules does it have?
I tried to search the implementation of a default copy constructor on the internet but I didn't find something that explains this behavior. Can anyone suggest something to read about this issue?
Upvotes: 2
Views: 2756
Reputation: 28178
When you have a derived class copy constructor such as...
C(const C& c) {...}
You might think this would call A's and B's copy ctors automatically, but it doesn't. The implicit behavior is as if you had written...
C(const C& c) : B() {...}
... And then B's B() does...
B() : A() {...}
If you want copy ctors to be called up to your base classes you need to explicitly specify that behavior like so...
C(const C& c) : B(c) {...}
Implicitly generated copy ctors already do this for you.
As far as your observation that operator=
is called in your situation, it isn't. I don't know why you think it is.
Upvotes: 4
Reputation:
Compile and run, check the comments in the code, it will be more clear:
#include <iostream>
class A{
public:
A()
{
}
A(const A& a)
{
std::cout << "Copy constructor FOR A is being called" << std::endl;
}
virtual ~A(){}
void foo(){}
};
class B : public A
{
public:
B()
{
}
B(const B& b)
{
std::cout << "Copy constructor FOR B is being called" << std::endl;
}
B& operator=(const B& b){return *this;}
virtual ~B()
{
}
virtual void foo(){}
};
class C : public B
{
public:
C()
{
}
//if you remove this copy constructor, instead of only C being called, both A and B's copy constructor will be called
C(const C& c)
{
std::cout << "Copy constructor FOR C is being called" << std::endl;
}
C& operator()(const C& c)
{
std::cout << "Operator is being called" << std::endl;
a_=c.a_;
return *this;
}
~C()
{
}
void foo()
{
}
protected:
A a_;
};
int main()
{
C* c = new C();
C c2(*c); //copy constructor C will be called since we declared one, otherwise both A's and B's copy constructor would be called
c2(c2); //here the operator() will be called but not above, changed that one to operator() since operator= didn't make sense
delete c;
std::cin.get();
return 0;
}
Upvotes: 0