给定多个派生类的基类,目标是创建一个包装类,允许STL容器使用基本接口查看对象,尽管事实上可能会将不同的派生类添加到容器中。 (见Retrieve data from heterogeneous 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());
}
This does not compile with g++ 4.7.2
现在,为了使用BaseWrapper
,我可以像这样实现一个公共移动构造函数:
BaseWrapper (BaseWrapper &&bw) { ptr_.swap(bw.ptr_); }
And this works fine。但是,如果我将其设为私有,it will not compile。
然而,我发现,I can instead define a private "copy" constructor(公开发布也是有效的)代替上述内容:
BaseWrapper (BaseWrapper &bw) { ptr_.swap(bw.ptr_); }
有人能告诉我这是否应该有用,为什么或为什么不呢?如果它应该工作,为什么我不能将移动构造函数设为私有?
您可以按照this link关注以更完整的方式说明上述内容的玩具程序。
答案 0 :(得分:4)
[删除了错误的诊断]
这实际上是在gcc 4.8上编译的。似乎gcc 4.7将BaseWrapper (const Base &)
作为复制构造函数(实际上不是),并隐式删除移动构造函数(如果它确实是一个复制构造函数,那么它将是预期的行为)。