我有一个实现Prototype pattern的类的hierar,我想使用移动语义来限制对象的深层复制。我尝试使用move()
成员函数调整模式,这意味着我不再需要原始对象。以下是我到目前为止的情况:
#include <iostream>
#include <utility>
#include <vector>
struct base
{
virtual ~base() { }
virtual base* clone() const = 0;
virtual base* move() = 0;
};
struct derived1 : public base
{
derived1() { std::cout << "derived1::derived1()\n"; }
derived1(const derived1&) { std::cout << "derived1::derived1(const derived1&)\n"; }
derived1(derived1&&) { std::cout << "derived1::derived1(derived1&&)\n"; }
virtual ~derived1() { }
virtual base* clone() const { return new derived1(*this); }
virtual base* move() { return new derived1(std::move(*this)); }
};
struct derived2 : public base
{
derived2() { std::cout << "derived2::derived2()\n"; }
derived2(const derived2&) { std::cout << "derived2::derived2(const derived2&)\n"; }
derived2(derived2&&) { std::cout << "derived2::derived2(derived2&&)\n"; }
virtual ~derived2() { }
virtual base* clone() const { return new derived2(*this); }
virtual base* move() { return new derived2(std::move(*this)); }
};
std::vector<base*> vec;
void foo(const base& obj)
{
vec.push_back(obj.clone());
}
void foo(base&& obj)
{
vec.push_back(obj.move());
}
int main()
{
derived1 d1;
derived2 d2;
foo(d1);
foo(d2);
foo(derived1());
foo(derived2());
}
当我运行它时,它表明使用了良好的构造函数:
derived1::derived1()
derived2::derived2()
derived1::derived1(const derived1&)
derived2::derived2(const derived2&)
derived1::derived1()
derived1::derived1(derived1&&)
derived2::derived2()
derived2::derived2(derived2&&)
到目前为止,似乎很好。我只是不确定这是否是rvalue引用的标准兼容用法。是否有一点我没想到会产生不良后果?
答案 0 :(得分:1)
对于重复的方法定义,我更喜欢CRTP。对于你的情况,我会声明如下:
template<typename TDerived>
class virtually_clonable : public base
{
public:
virtual base* clone() override
{
return new TDerived(*AsDerived());
}
virtual base* move() override
{
return new TDerived(std::move(*AsDerived()));
}
private:
TDerived* AsDerived()
{
return static_cast<TDerived*>(this);
}
};
在实施课程时:
class derived1 : public virtually_clonable<derived1>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
class derived2 : public virtually_clonable<derived2>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
顺便说一句,您可能希望返回shared_ptr
个对象而不是原始指针。通常情况下,克隆类型而不是unique_ptr
。