4

给定多个派生类的基类,目标是创建一个包装类,允许 STL 容器查看具有基接口的对象,尽管实际上可能将不同的派生类添加到容器中。(请参阅从异构 std::list 中检索数据)。

经过一番修改,我想出了一个新的派生类,它是unique_ptr基类的包装器。但是,移动构造函数让我感到困惑。

class Base {
    friend class BaseWrapper;
    virtual Base * clone () const = 0;
public:
    virtual ~Base () {}
    //... public interface
};

class Derived : public Base {
    //... specific members for derived class
    Base * clone () const { return new Derived(*this); }
public:
    //... implement public interface
};

class BaseWrapper : public Base {
    std::unique_ptr<Base> ptr_;
    Base * clone () const { return ptr_->clone(); }
public:
    BaseWrapper (const Base &b) : ptr_(b.clone()) {}
    //... implement public interface by forwarding to ptr_
};

typedef std::list<BaseWrapper> BaseList;

int main () {
    BaseList l;
    l.push_back(Derived());
}

这不能与 g++ 4.7.2 一起编译

现在,为了使用BaseWrapper,我可以像这样实现一个公共移动构造函数:

    BaseWrapper (BaseWrapper &&bw) { ptr_.swap(bw.ptr_); }

这很好用。但是,如果我将其设为私有,它将无法编译

但是,我发现除了上面的之外,我可以定义一个私有的“复制”构造函数(当然,使其公开也可以):

    BaseWrapper (BaseWrapper &bw) { ptr_.swap(bw.ptr_); }

有人可以告诉我这是否应该工作,为什么或为什么不?如果它应该工作,为什么我不能将移动构造函数设为私有?

您可以点击此链接以更完整地说明上述内容的玩具程序。

4

1 回答 1

4

[删除错误诊断]

这实际上是在 gcc 4.8 上编译的。似乎 gcc 4.7 将BaseWrapper (const Base &)其作为复制构造函数(实际上不是),并隐式删除了移动构造函数(如果它确实是复制构造函数,这将是预期的行为)。

于 2013-04-04T21:10:26.497 回答