"Almost default" copy constructor (& assignment operator) in C++
Asked Answered
R

1

13

A common thing I find myself doing is making "almost default" copy constructors and assignment operators. That is, I find myself in situations where the compiler supplied copy and assignment operators would work for most of the data members, but there's a particular data member which needs to be handled differently. This means that I have to explicitly create a copy constructor/assignment operator, including explicitly listing all the data members which have simple copy semantics. This can get annoying for classes where there are a fair number of data members, or later on when member variables are added but aren't added to the copy constructor/assignment operator.

Is there some way to tell the C++ compiler that an explicitly declared copy constructor/assignment operator should work like an implicit one, except for some additional code that's run afterwards? (And is such a syntax C++98 compatible, or does it need C++11 or C++14 support?)

Ransell answered 11/7, 2014 at 23:38 Comment(1)
Implement a proper RAII wrapper for that one data member, then default constructors would work for everything.Emissive
V
13

If you can isolate the specific handling in a proper RAII wrapper as Igor Tandetnik suggested: go for that.

If you still need specific processing in the copy constructor and/or assignment operator (such as register the object creation/assignment in a container or log), you can group the data members that can be default copy constructed/assigned into a separate class that you use as a base class or data member, which you handle as composite, thus:

struct x_base {
  int a,b,c,d;
  std::string name;
};

struct x : x_base {
     x(const x& other)
         : x_base(other) 
     {
         descr = "copied ";
         descr += name;
         descr += " at ";
         descr += CurrentTimeAsString();
         std::cout << descr << "\n";
     }
     void operator = (const x& other)
     {
         x_base::operator =(other); 
         descr = "assigned ";
         descr += name;
         descr += " at ";
         descr += CurrentTimeAsString();
         std::cout << descr << "\n";
     }
     std::string descr;
};

When you later add data members that don't need specific handling, you can simply add them to x_base.

Viscount answered 12/7, 2014 at 0:22 Comment(1)
This takes advantage of principle that implicitly-defined copy constructor for a non-union class performs a memberwise copy of its bases and members (Standard C++, sect 12.8 pt 15). Note however that this has some constraints on the order the member copy is done.Karimakarin

© 2022 - 2024 — McMap. All rights reserved.