Home:ALL Converter>Delegating copy constructor and const data initialization

Delegating copy constructor and const data initialization

Ask Time:2017-08-01T16:38:17         Author:Sergey

Json Formatter

I have a class A with lots of data members, some of which are constant. All data members have proper copy constructors, so I want to default a copy constructor of my class:

class A
{
public:
        A() : a(1) {}
        A(const A& op) = default;
private:
        // ... Lots of constant and non-constant member data ...
        const int a;
};

Then, I want to write a constructor which accepts a reference to A and a value which should initialize one of constant data members:

A(const A& op, const int a_);

Here op should be copied, and a should be initialized with a_ after that or instead of copying. I would like to avoid manual initialization of all data members by delegating to a copy constructor, but how to overwrite my const data member in this case? For example:

// Illegal: constructor delegation can't be mixed with field initialization.
A(const A& op, const int a_) : A(op), a(a_) {}

// Illegal: attempt to assign constant member.
A(const A& op, const int a_) : A(op) { a = a_; } 

// Hack. May lead to UB in some cases.
A(const A& op, const int a_) : A(op)
{
    *(const_cast<int*>(&a)) = a_;
    // ... or same tricks with memcpy ...
}

Obviously, all of these approaches are evil as they try to initialize a twice.

Another solution is to move all constant data to a base class and write all needed ctors, but it looks to verbose.

Is there a cleaner way to implement A(const A&, int a_)?

Author:Sergey,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/45432891/delegating-copy-constructor-and-const-data-initialization
Serge Ballesta :

Unfortunately, C++ const field initialization is a very special case with specific syntax, so is constructor delegation, and the constructor syntax has no provision to mix them, so there can be no clean and neat solution here (at least for current C++ versions, maybe later...). The best I can imagine is:\n\nclass A\n{\npublic:\n A() : a(1) {}\n A(const A& op):\n const_field1(op.const_field1),..., a(op.a) // all const fields here\n { init() };\n A(const A& op, int a_):\n const_field1(op.const_field1),..., a(a)) // dup line at editor level\n\nprivate:\n void init(void) {\n // init non const fields here\n }\n // ... Lots of constant and non-constant member data ...\n const int a;\n};\n\n\nIt does not make sense if you have only the copy ctor and one single additional one, but it could ease code maintenability if you have many additional ctors. It is a pity that only non const field setting can be factorized across different ctors with a private method, but C++ standard is like that.",
2017-08-01T09:39:54
yy