Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use both default and custom copy constructor in C++?

I have a long class with a lot of data members. I want to write a copy constructor for it. But, if I write my own copy constructor, I lose access to the default copy constructor.

I just want to repair a few pointers in my own copy constructor. So I want to have a shallow copy of the object which can be done by the default copy constructor.

Is there a possibility to access the default copy constructor when I have my own copy constructor?

like image 635
pablo Avatar asked Sep 14 '12 10:09

pablo


People also ask

Can you have multiple copy constructors?

A class can have multiple copy constructors, e.g. both T::T(const T&) and T::T(T&). If some user-defined copy constructors are present, the user may still force the generation of the implicitly declared copy constructor with the keyword default .

Can there be two default constructors?

There can be multiple constructors in a class. However, the parameter list of the constructors should not be same. This is known as constructor overloading.

Does copy constructor call default constructor?

The answer is No. The creation of the object memory is done via the new instruction. Copy constructor is then in charge of the actual copying (relevant only when it's not a shallow copy, obviously). You can, if you want, explicitly call a different constructor prior to the copy constructor execution.

What happens if you use the default copy constructor for vector?

The default copy constructor will copy all members – i.e. call their respective copy constructors. So yes, a std::vector (being nothing special as far as C++ is concerned) will be duly copied.


2 Answers

Wrap the things you don't want to change in a struct, and derive (privately) from it. In your copy constructor, simply invoke the copy constructor of your base class.

like image 155
James Kanze Avatar answered Oct 08 '22 22:10

James Kanze


No you cannot have both default and your own copy c-tor.

But there are two workarounds with this problem:


1 Enclose your pointers in some class with defined copy semantics

Example:

class A {
public:
private:
   int trivial1;
   int trivial2;
   ...
   SomePointer  nontrivialMember;
};

class SomePointer {
public:
  SomePointer(const SomePointer&); // here the non trivial part of A copy semantics
  int* nonTrivialMember;
};

2 Enclose the trivial parameters in some trivial structure

Example:

class A {
public:
   A(const A& o) : data(o.data) {
     // non trivial part
   }
private:
   struct Data {
     int trivial1;
     int trivial2;
     ...
   } data;
   int* nontrivialMember;
};

I would always select the first solution.

[UPDATE]

There is also 3rd solution, very similar to my second, enclose your trivial part in privately inherited base class. I'd still prefer the 1st solution.

like image 34
PiotrNycz Avatar answered Oct 08 '22 21:10

PiotrNycz