2012-07-15 38 views
1

我有一个类实现Prototype pattern hierarchie,我想使用移动语义来限制对象的深度复制。我试图用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&&) 

到目前为止,它似乎不错。我只是不确定这是否是右值引用的标准兼容使用。有没有我没有想到的一点会产生不良结果?

+3

听起来像[函数ref-qualifiers]的工作(http://stackoverflow.com/a/8610728/46642)。到目前为止,只有在叮当中才有,我想。 – 2012-07-15 21:58:18

+0

@ R.MartinhoFernandes这看起来像一个有趣的功能,但我不明白你的意思。我应该如何使用它? – authchir 2012-07-15 23:22:37

+4

你可以重载'clone()'为左值和右值而不是使用不同名称的函数。 – 2012-07-15 23:24:51

回答

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

相关问题