class A{
public:
int *a;
A(int value){
this->a = newint(value);
}
~A(){
deletethis->a;
}
A(const A &other){
this->a = newint(*other.a);
}
};
class B{
public:
int *b;
B(int value){
this->b = newint(value);
}
~B(){
deletethis->b;
}
};
int main(){
{
A x(42);
{
A y(x);
}
std::cout << *x.a << std::endl;
}
//Everything OK up to this point.
{
B x(42);
{
B y(x);
}
//Oops! Both x.b and y.b were pointing to the same int. Now that y has
//been destructed, x.b points to an invalid address, so the next line
//will trigger undefined behavior.
std::cout << *x.b << std::endl;
}
}
In general, copy constructors are useful whenever you have classes that own resources (memory, system objects, etc.).
The members can be non-trivial. For example a pointer to "owned" memory. The implicit implementation does "shallow copy", which is almost always a huge mistake.
I wish I'd learned C++ back in the day. I started coding in '83 and never really got past pascal.
@helios - you laid it out sensibly and it sticks. Much appreciated for that.
@keskiverto - You answered my bigger, unasked question: Isn't a Copy Ctor just a parameterized Ctor that makes "copies" of whatever to sel member vars? I may not be saying that the right way, so I hope you catch my drift.
Isn't a Copy Ctor just a parameterized Ctor that makes "copies" of whatever to sel member vars?
That would be what a trivial copy constructor does, such as the default one, or the one you wrote in your example above. It just literally copies the values of the members from one object to another.
What a copy constructor should do is create a copy of the state of an object such that the new object has semantics that make sense in the program.
For example, consider this:
1 2 3 4 5
String a;
a = "hello";
String b = a;
b = "goodbye";
std::cout << a;
Should the output be "hello", or "goodbye"? Either option is valid. There's different ways to implement the copy constructor to get one behavior or the other.