C++如何在子类拷贝构造函数中调用模板父类的拷贝构造函数
如何在子类的拷贝构造函数中调用模板父类的拷贝构造函数?
问题背景
现有模板基类Parent<T>和派生类Child<T>,派生类拷贝构造中目前通过setDims()方法给父类成员赋值,需要改为直接调用父类拷贝构造完成父类成员复制,原实现代码如下:
#include<vector> #include <iostream> template <typename T> class Parent { public: Parent() {}; const std::vector<T>& getDims() const { return m_dims; }; void setDims(const std::vector<T> dims) { m_dims = dims; }; Parent(const Parent& p) { m_dims = p.getDims(); }; private: std::vector<T> m_dims; }; template <typename T> class Child : public Parent<T> { public: Child() {}; const std::vector<T>& getCenter() const { return m_center; }; void setCenter(const std::vector<T> center) { m_center = center; }; Child(const Child& c) { m_center = c.getCenter(); // 如何触发父类的拷贝构造函数来复制m_dims,而非使用下方的写法 this->setDims(c.getDims()); } private: std::vector<T> m_center; }; int main(){ Child<int> child1; child1.setDims({3, 1, 1, 1}); // 父类方法 child1.setCenter({1, 2, 3, 4}); // 子类方法 Child<int> child2 = child1; return 0; }
实现方法
基类构造函数的调用必须在派生类构造函数的初始化列表中完成,不能写在构造函数体内——如果不在初始化列表显式指定基类构造,编译器会默认先调用基类的无参构造,等进入函数体时父类部分已经初始化完成,后续再给父类成员赋值就不是拷贝构造的逻辑了。
针对模板继承的场景,直接在初始化列表中显式调用Parent<T>的拷贝构造即可,派生类对象可以隐式转换为基类的const引用,完全匹配父类拷贝构造的入参要求。
修正后的Child类拷贝构造代码如下:
Child(const Child& c) : Parent<T>(c) { // 初始化列表调用父类拷贝构造 m_center = c.getCenter(); }
如果要优化效率,子类自身的成员也可以放到初始化列表中初始化:
Child(const Child& c) : Parent<T>(c), m_center(c.getCenter()) {}
替换原代码中Child的拷贝构造后,拷贝child1生成child2时就会直接调用父类的拷贝构造复制m_dims成员,不需要再通过setDims方法二次赋值。
注意:模板类继承场景下,必须用
Parent<T>明确指定基类类型,不能直接写Parent(c),否则会因为模板两阶段查找机制找不到基类标识导致编译报错。
内容的提问来源于stack exchange,提问作者shashashamti2008
相关产品推荐
相关产品推荐

