如何在没有复制构造函数的情况下克隆对象
How to clone an object without copy constructor
根据CppCoreGuideline,我应该禁用基类的复制构造函数并提出一个克隆方法:https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-copy-virtual
例如:
class B {
public:
explicit B() = default;
B(B&&) = default; // Move constructor
B& operator=(B&&) = default; // Move assignment operator
B(const B&) = delete; // Copy constructor
B& operator=(const B&) = delete; // Copy assignment
virtual ~B() = default;
virtual unique_ptr<B> clone()
{
return unique_ptr<B>{new B{*this}}; // how do this without copy constructor ?
}
private:
int c;
int d;
};
class D : public B {
public:
explicit D() = default;
D(D&&) = default; // Move constructor
D& operator=(D&&) = default; // Move assignment operator
D(const B&) = delete; // Copy constructor
D& operator=(const D&) = delete; // Copy assignment
virtual ~D() = default;
virtual unique_ptr<B> clone() override
{
// how can I copy all private data member of base class ???
}
};
但是如何在克隆方法中复制所有私有数据成员?显然,我将使用 CRTP 模式:C++:深度复制基类指针
我认为
最简单的方法是实际使特殊成员protected
而不是deleted
。这仍然可以防止切片,但更容易实现clone()
。请注意,复制成员和移动成员都需要以这种方式处理。
class B {
public:
// if this is truly intended to be a polymorphic base class, it probably
// doesn't make sense for the base to be able to clone itself.
virtual unique_ptr<B> clone() = 0;
protected:
B(B const& ) = default;
B& operator=(B const& ) = default;
private:
int c;
int d;
};
这也允许派生类轻松执行此操作:
class D : public B {
public:
D(D const& ) = default; // this is safe now
D& operator=(D const& ) = default;
unique_ptr<B> clone() override {
return unique_ptr<D>(new D(*this));
}
// ...
};
与其禁用复制构造函数,不如考虑将其标记为受保护。这样,类的客户端就不会意外创建副本,但类的实例可以根据需要调用复制构造函数来实现clone
函数。可以使用复制构造函数的默认版本,前提是您没有执行任何显式资源管理。然后,要实现clone
,您可以执行以下操作:
virtual unique_ptr<B> clone() override
{
return make_unique<D>(*this);
}
这将调用对象自己的(受保护的)复制构造函数,而该构造函数又将调用基的(受保护的)复制构造函数等。
请注意,此处无需使用 CRTP。使用好的老式复制构造函数应该是你所需要的。
相关文章:
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 在这种情况下,java对象是否可以调用本机函数
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- 在不复制临时对象的情况下延长其生存期
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在不销毁对象的情况下返回对象列表
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 在没有默认构造函数的情况下创建的派生对象
- 如何在不使用new的情况下保持在其他对象中创建的对象存活?
- 如何在没有 std::move 的情况下移动临时对象
- 如何在不复制的情况下操作 QByteArray 对象?
- 在单元测试中,如何在不使用 operator== 的情况下比较两个对象,这可能会错过新成员?
- 如何在不使用 "new" 关键字的情况下解除分配创建的对象的内存?
- 如何防止类中的类对象尝试在没有默认构造函数的情况下自动构造自身?
- 在没有堆的情况下用两种方法构造对象
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C ++:如何在不创建对象的情况下在主函数中调用方法
- 为什么成员变量会更改,但在这种情况下对象的地址保持不变?