You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 12:03:23