在用户定义复制构造函数中隐式复制构造函数的使用
Use of the Implicit Copy Constructor in User-Defined Copy Constructor
我有一个相当大且冗长的类,其中隐式生成的复制构造函数几乎完全正确,除了一个特定的字段。
是否有一种方法可以编写用户定义的复制构造函数,调用隐式版本,然后在末尾添加一或两行?或者我必须编写一个冗长的、(而且无聊的、容易输入错误的)用户定义的复制构造函数,它主要重复隐式的复制构造函数?
class MySimpleObject
{
private:
FieldA m_fieldA;
FieldB m_fieldB;
[... repeated a lot...]
SpecialField m_trickyField;
public:
MySimpleObject(const MySimpleObject& other)
{
ImplicitCopyCtor(*this,other); // This is what I want to simplify, instead of copying all the fields by hand.
m_trickyField.DoCloneSeparately(other.m_trickyField);
}
};
注意: SpecialField是由第三方库提供的,所以我不能重构或修改它。我不知道为什么不能正确地复制,但是它不能,我认为有一个很好的理由。我喜欢将它包装在一个行为正常的类中的想法。我来查一下。
软件工程的基本定理是你的朋友:
struct MakeSpecialSnowflakeLessSpecial
{
MakeSpecialSnowflakeLessSpecial(const MakeSpecialSnowflakeLessSpecial& other)
{
m_trickyField.DoCloneSeparately(other.m_trickyField);
}
SpecialField m_trickyField;
};
class MySimpleObject
{
private:
FieldA m_fieldA;
FieldB m_fieldB;
[... repeated a lot...]
MakeSpecialSnowflakeLessSpecial m_special;
public:
MySimpleObject(const MySimpleObject&) = default;
};
不,没有。
最好的办法是修复有问题的成员。
一个快速的解决方案可能是将其包装在一个类中,以保持其复制语义。
我能想到有两种方法来解决你的问题:
- 把正常的东西放在一个额外的结构体中,你从private继承。
- 将需要特殊处理的字段类型包装到另一个类型中,以便在那里实现所需的复制语义。
第一个解决方案是这样的:
struct MySimpleObjectDefaultData
{
FieldA m_fieldA;
FieldB m_fieldB;
// [... repeated a lot...]
}
class MySimpleObject : private MySimpleObjectDefaultData
{
private:
SpecialField m_trickyField;
public:
MySimpleObject(const MySimpleObject& other)
: MySimpleObjectDefaultData( other )
{
m_trickyField.DoCloneSeparately(other.m_trickyField);
}
};
这对于代码的其余部分来说侵入性较小,因为访问权限和字段的类型保持完全相同。要使此解决方案工作,您不需要触及现有代码的其余部分。此外,这个解决方案更通用一些,因为实际上可以手动将任何后处理步骤应用于编译器生成的复制构造函数。
第二个是这样的:
struct SpecialFieldWrapper : SpecialField
{
using SpecialField::SpecialField;
SpecialFieldWrapper( const SpecialFieldWrapper & other )
{
DoCloneSeparately( other.m_trickyField );
}
};
class MySimpleObject
{
private:
FieldA m_fieldA;
FieldB m_fieldB;
[... repeated a lot...]
SpecialFieldWrapper m_trickyField;
public:
MySimpleObject(const MySimpleObject& other)
{
ImplicitCopyCtor(*this,other); // This is what I want to simplify, instead of copying all the fields by hand.
m_trickyField.DoCloneSeparately(other.m_trickyField);
}
};
这个解决方案可能比第一个更容易阅读。但是,类型会发生轻微变化,这可能需要对代码进行进一步更改。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用