使用多态与抽象类CObject实现CWindow等元素时遇实例化错误
解决抽象类CObject实例化错误的多态实现方案
嘿,这个问题我太熟了——你碰到的是抽象类多态拷贝的经典坑!咱们一步步拆解问题,搞定它:
首先明确错误根源:你写的CObject包含纯虚函数print,所以它是抽象类,C++明确禁止直接实例化抽象类。而你在add方法里用make_unique<CObject>(src)试图构造它的对象,这直接触发了编译器报错。
要在多态场景下存储不同子类对象的拷贝,我们需要用**多态克隆(原型模式)**来解决——让每个子类自己负责创建自身的拷贝实例。
步骤1:给抽象类CObject添加纯虚克隆方法
在CObject中新增一个纯虚的clone方法,让子类实现它来返回自身的拷贝:
class CObject { public: CObject(const int id, const string &title, const CRect &pos) : m_id(id), m_title(title), m_pos(make_unique<CRect>(pos)) {} // 纯虚函数,标记CObject为抽象类 virtual void print(ostream &os) const = 0; // 新增纯虚克隆方法,返回子类的拷贝 virtual unique_ptr<CObject> clone() const = 0; // 修改add方法,用clone替代直接构造CObject virtual void add(const CObject &src) { m_src.push_back(src.clone()); // 这里不再直接实例化抽象类 } private: int m_id; string m_title; unique_ptr<CRect> m_pos; vector<unique_ptr<CObject>> m_src; // 假设这是你存储子元素的容器 };
步骤2:子类(比如CWindow)实现clone方法
每个继承CObject的子类都要重写clone方法,同时要正确实现拷贝构造函数,确保所有成员都被正确拷贝:
class CWindow : public CObject { public: // 子类构造函数,调用基类构造逻辑 CWindow(const int id, const string &title, const CRect &pos, /* 子类自定义参数 */) : CObject(id, title, pos) /* 初始化子类自己的成员 */ {} // 重写纯虚print方法 void print(ostream &os) const override { os << "Window ID: " << m_id << ", Title: " << m_title << endl; // 示例实现 } // 重写clone方法,返回CWindow的拷贝实例 unique_ptr<CObject> clone() const override { return make_unique<CWindow>(*this); // 调用拷贝构造创建子类拷贝 } // 实现子类的拷贝构造函数,确保基类和子类成员都被拷贝 CWindow(const CWindow &other) : CObject(other) { // 在这里拷贝CWindow自己的成员变量(如果有的话) } // 可选:禁止移动构造,避免意外的资源转移 CWindow(CWindow &&) = delete; };
为什么这样可行?
当你调用src.clone()时,虽然src是CObject类型的引用,但它实际指向的是子类(比如CWindow)的对象,所以会触发子类重写的clone方法,返回子类的实例,最终被包装成unique_ptr<CObject>存入容器,完美实现多态场景下的对象存储与拷贝。
注意事项
- 所有继承
CObject的子类都必须实现clone方法,否则子类也会变成抽象类,无法实例化。 - 子类的拷贝构造函数要确保所有成员(包括基类和子类自身的)都被正确拷贝,避免浅拷贝导致的资源问题。
内容的提问来源于stack exchange,提问作者Valery Lyalin
相关产品推荐
相关产品推荐

