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_)
?
a_
unconstrained? – Dailya
anda_
are not necessarily integer, it's just an example. In general, the constructor accepts a const reference to a value. – Awfullyint a_
isn'tint const a_
? – Jeneejenei