(C++) 如何为具有唯一指针作为数据成员的 class 编写克隆方法?
(C++) How to write a clone method for a class which has a unique pointer as a data member?
我有以下设置:
class Base {
private:
// data members
public:
// methods
// pure virtual methods
virtual Base* clone() const =0;
}
class Derived : public Base{
private:
// more data members
public:
// more methods
// pure virtual methods overridden
Derived* clone() const override{
return new Derived(*this);
}
我现在想介绍一个新的派生 class,在装饰器模式的上下文中,它有一个指向 Base class 对象作为数据成员的唯一指针。我的问题是如何正确实现 clone() 方法,因为“标准”实现会导致编译时错误,因为无法复制唯一指针:
class DecoratedDerived : public Base{
private:
unique_ptr<Base> ptr;
// more data members
public:
// more methods
// pure virtual methods overridden
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this); // compiler error
}
一个解决方案是在克隆方法中构造一个新的 DecoratedDerived class 对象(通过显式深度复制与当前对象关联的所有成员),然后将指针传递给它。但是,如果 class 有很多其他成员,这将非常耗时。
我还应该说我只使用了一个唯一指针,因为这似乎是现代 C++ 中使用的标准智能指针。特别是在我使用 C+11 之前,我刚刚设计了我自己的智能指针,它负责所有的内存管理等,因此对于那种类型的智能指针,装饰 [=23= 中的克隆方法不会有问题].
在此先感谢您的帮助!
这是可能的实现,当新的 DecoratedDerived
被构造时,成员项目也被克隆:
class Base {
public:
virtual std::unique_ptr<Base> clone() const = 0;
};
class Empty : public Base {
public:
std::unique_ptr<Base> clone() const override {
return std::make_unique<Empty>();
}
};
class DecoratedDerived : public Base {
private:
std::unique_ptr<Base> ptr;
public:
DecoratedDerived() : ptr{std::make_unique<Empty>()} {}
DecoratedDerived(std::unique_ptr<Base> wrap) : ptr{std::move(wrap)} {}
std::unique_ptr<Base> clone() const override {
return std::make_unique<DecoratedDerived>(ptr->clone());
}
};
https://godbolt.org/z/sG3zTehb1
Empty
class 是避免检查 nullptr
.
的好方法
另请注意,因为您正在使用 unique_ptr
我已经在其他地方介绍了它们,当它看起来合乎逻辑时。
只需向 DecoratedDerived
添加一个复制构造函数,即 clone()
的数据成员,例如:
class DecoratedDerived : public Base {
private:
unique_ptr<Base> ptr;
// ...
public:
DecoratedDerived(const DecoratedDerived &src)
: Base(src), ptr(src.ptr ? src.ptr->clone() : nullptr)
{
}
// ...
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this);
}
};
我有以下设置:
class Base {
private:
// data members
public:
// methods
// pure virtual methods
virtual Base* clone() const =0;
}
class Derived : public Base{
private:
// more data members
public:
// more methods
// pure virtual methods overridden
Derived* clone() const override{
return new Derived(*this);
}
我现在想介绍一个新的派生 class,在装饰器模式的上下文中,它有一个指向 Base class 对象作为数据成员的唯一指针。我的问题是如何正确实现 clone() 方法,因为“标准”实现会导致编译时错误,因为无法复制唯一指针:
class DecoratedDerived : public Base{
private:
unique_ptr<Base> ptr;
// more data members
public:
// more methods
// pure virtual methods overridden
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this); // compiler error
}
一个解决方案是在克隆方法中构造一个新的 DecoratedDerived class 对象(通过显式深度复制与当前对象关联的所有成员),然后将指针传递给它。但是,如果 class 有很多其他成员,这将非常耗时。
我还应该说我只使用了一个唯一指针,因为这似乎是现代 C++ 中使用的标准智能指针。特别是在我使用 C+11 之前,我刚刚设计了我自己的智能指针,它负责所有的内存管理等,因此对于那种类型的智能指针,装饰 [=23= 中的克隆方法不会有问题].
在此先感谢您的帮助!
这是可能的实现,当新的 DecoratedDerived
被构造时,成员项目也被克隆:
class Base {
public:
virtual std::unique_ptr<Base> clone() const = 0;
};
class Empty : public Base {
public:
std::unique_ptr<Base> clone() const override {
return std::make_unique<Empty>();
}
};
class DecoratedDerived : public Base {
private:
std::unique_ptr<Base> ptr;
public:
DecoratedDerived() : ptr{std::make_unique<Empty>()} {}
DecoratedDerived(std::unique_ptr<Base> wrap) : ptr{std::move(wrap)} {}
std::unique_ptr<Base> clone() const override {
return std::make_unique<DecoratedDerived>(ptr->clone());
}
};
https://godbolt.org/z/sG3zTehb1
Empty
class 是避免检查 nullptr
.
另请注意,因为您正在使用 unique_ptr
我已经在其他地方介绍了它们,当它看起来合乎逻辑时。
只需向 DecoratedDerived
添加一个复制构造函数,即 clone()
的数据成员,例如:
class DecoratedDerived : public Base {
private:
unique_ptr<Base> ptr;
// ...
public:
DecoratedDerived(const DecoratedDerived &src)
: Base(src), ptr(src.ptr ? src.ptr->clone() : nullptr)
{
}
// ...
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this);
}
};