委托复制构造函数和常量数据初始化
Delegating copy constructor and const data initialization
我有一个 class A
有很多数据成员,其中一些是常量。所有数据成员都有适当的复制构造函数,所以我想默认我的 class:
的复制构造函数
class A
{
public:
A() : a(1) {}
A(const A& op) = default;
private:
// ... Lots of constant and non-constant member data ...
const int a;
};
然后,我想编写一个构造函数,它接受对 A
的引用和一个应该初始化常量数据成员之一的值:
A(const A& op, const int a_);
这里应该复制op
,然后a
应该用a_
初始化,或者不复制。我想通过委托给复制构造函数来避免手动初始化所有数据成员,但是在这种情况下如何覆盖我的 const 数据成员呢?
例如:
// 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 ...
}
显然,所有这些方法都是邪恶的,因为它们试图初始化 a
两次。
另一种解决方案是将所有常量数据移动到基class 并编写所有需要的 ctors,但它看起来很冗长。
是否有更简洁的方法来实现 A(const A&, int a_)
?
具有完整初始化列表的复制构造函数怎么样?由于您的数据是常量,因此您只能使用初始化列表为其分配一个值。
A(const A& op, int a_) :
prop_a(op.prop_a_),
prop_b(op.prop_b_),
// continue for all members ...
a(a_) // except a
{
}
不幸的是,C++ const 字段初始化是一种非常特殊的情况,具有特定的语法,构造函数委托也是如此,并且构造函数语法没有规定混合它们,所以这里不可能有干净整洁的解决方案(至少对于当前的 C++ 版本,也许以后……)。我能想到的最好的是:
class A
{
public:
A() : a(1) {}
A(const A& op):
const_field1(op.const_field1),..., a(op.a) // all const fields here
{ init() };
A(const A& op, int a_):
const_field1(op.const_field1),..., a(a)) // dup line at editor level
private:
void init(void) {
// init non const fields here
}
// ... Lots of constant and non-constant member data ...
const int a;
};
如果您只有一个复制 ctor 和一个附加的 ctor,那是没有意义的,但是如果您有许多附加的 ctor,它可以简化代码的可维护性。遗憾的是,只有非 const 字段设置才能使用私有方法在不同的 ctors 之间分解,但 C++ 标准就是这样。
我有一个 class A
有很多数据成员,其中一些是常量。所有数据成员都有适当的复制构造函数,所以我想默认我的 class:
class A
{
public:
A() : a(1) {}
A(const A& op) = default;
private:
// ... Lots of constant and non-constant member data ...
const int a;
};
然后,我想编写一个构造函数,它接受对 A
的引用和一个应该初始化常量数据成员之一的值:
A(const A& op, const int a_);
这里应该复制op
,然后a
应该用a_
初始化,或者不复制。我想通过委托给复制构造函数来避免手动初始化所有数据成员,但是在这种情况下如何覆盖我的 const 数据成员呢?
例如:
// 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 ...
}
显然,所有这些方法都是邪恶的,因为它们试图初始化 a
两次。
另一种解决方案是将所有常量数据移动到基class 并编写所有需要的 ctors,但它看起来很冗长。
是否有更简洁的方法来实现 A(const A&, int a_)
?
具有完整初始化列表的复制构造函数怎么样?由于您的数据是常量,因此您只能使用初始化列表为其分配一个值。
A(const A& op, int a_) :
prop_a(op.prop_a_),
prop_b(op.prop_b_),
// continue for all members ...
a(a_) // except a
{
}
不幸的是,C++ const 字段初始化是一种非常特殊的情况,具有特定的语法,构造函数委托也是如此,并且构造函数语法没有规定混合它们,所以这里不可能有干净整洁的解决方案(至少对于当前的 C++ 版本,也许以后……)。我能想到的最好的是:
class A
{
public:
A() : a(1) {}
A(const A& op):
const_field1(op.const_field1),..., a(op.a) // all const fields here
{ init() };
A(const A& op, int a_):
const_field1(op.const_field1),..., a(a)) // dup line at editor level
private:
void init(void) {
// init non const fields here
}
// ... Lots of constant and non-constant member data ...
const int a;
};
如果您只有一个复制 ctor 和一个附加的 ctor,那是没有意义的,但是如果您有许多附加的 ctor,它可以简化代码的可维护性。遗憾的是,只有非 const 字段设置才能使用私有方法在不同的 ctors 之间分解,但 C++ 标准就是这样。