当前位置: 首页 > article >正文

C++ 语言特性11 - 继承构造函数

一:概述

        在C++中,直到C++11标准发布之前,派生类(子类)不能直接继承基类的构造函数。如果基类有多个构造函数,派生类需要显式地为每一个基类构造函数编写对应的派生类构造函数。这不仅增加了代码量,也提高了维护成本,因为基类构造函数的任何修改都需要在所有派生类中进行相应的更新。

        C++11标准引入了继承构造函数的概念,允许派生类通过using声明来继承基类的构造函数。这使得派生类可以直接使用基类的构造函数来初始化其继承的基类部分,而不需要在派生类中显式地重写或复制这些构造函数的初始化代码

二:例子

class Base {
public:
    Base(int x) : value(x) {}
    Base(double x) : value(static_cast<int>(x)) {}
    
private:
    int value;
};

class Derived : public Base {
public:
    using Base::Base;  // 继承构造函数

    // 派生类特有的成员和方法
    void print() const {
        std::cout << "Value: " << value << std::endl;
    }
};

int main() {
    Derived d1(10);       // 调用 Base(10)
    Derived d2(3.14);     // 调用 Base(3.14)
    d1.print();
    d2.print();
    return 0;
}

三:使用继承构造的注意事项

 

  • 访问权限: 只有公开(public)或受保护(protected)的基类构造函数可以被派生类继承。私有(private)构造函数不能被继承。

class Base {
private:
    Base(int x) {}  // 私有构造函数
};

class Derived : public Base {
public:
    using Base::Base;  // 错误:不能继承私有构造函数
};
  • 构造函数的匹配: 派生类继承的构造函数必须与基类的构造函数具有相同的参数类型和顺序。

class Base {
public:
    Base(int x) {}
};

class Derived : public Base {
public:
    using Base::Base;  // 错误:参数类型不匹配
    Derived(double x) : Base(x) {}  // 尝试将double转换为int
};
  • 继承构造函数的声明顺序using声明必须在派生类中所有成员定义之前出现,包括构造函数和析构函数。

class Base {
public:
    Base(int x) {}
};

class Derived : public Base {
public:
    int value;
    using Base::Base;  // 错误:声明顺序不正确
};
  • 参数的默认值: 基类构造函数中的默认参数值不会被继承。派生类继承的构造函数将忽略这些默认值。

class Base {
public:
    Base(int x = 10) {}  // 带有默认参数的构造函数
};

class Derived : public Base {
public:
    using Base::Base;  // 默认参数不会被继承
};
  • 构造函数的重定义: 如果派生类定义了自己的构造函数,那么与基类构造函数具有相同签名的继承构造函数将被覆盖。

class Base {
public:
    Base(int x) {}
};

class Derived : public Base {
public:
    Derived(int x) : Base(x) {}  // 重定义构造函数
    using Base::Base;  // 错误:与派生类的构造函数冲突
};
  • 多重继承: 在多重继承的情况下,派生类可能会从多个基类继承构造函数。如果构造函数的参数列表相同,派生类需要明确指定使用哪个基类的构造函数。

class Base1 {
public:
    Base1(int x) {}
};

class Base2 {
public:
    Base2(int x) {}
};

class Derived : public Base1, public Base2 {
public:
    using Base1::Base1;  // 错误:与Base2构造函数冲突
    using Base2::Base2;
};
  • 继承与类模板: 在模板类中使用继承构造函数时,需要确保模板参数不会影响构造函数的可行性。

template <typename T>
class Base {
public:
    Base(T x) {}
};

class Derived : public Base<int> {
public:
    using Base::Base;  // 错误:模板参数导致构造函数不匹配
};
  • 继承构造函数与默认构造函数: 如果派生类使用了继承构造函数,编译器不会自动生成默认构造函数,除非基类也没有默认构造函数。

class Base {
public:
    Base(int x) {}
};

class Derived : public Base {
public:
    using Base::Base;  // 没有默认构造函数
};


http://www.kler.cn/news/330390.html

相关文章:

  • 洞悉go.dev
  • 集师专属心理咨询 心理培训 心理知识服务小程序搭建 专属知识付费小程序搭建
  • VScode 自定义代码配色方案
  • 关于 Latex 使用 BibTeX 进行参考文献管理的相关
  • 数据资料安全治理新时代,AI/ML 来助力!
  • Find My汽车钥匙|苹果Find My技术与钥匙结合,智能防丢,全球定位
  • SD card + Arduino IDE 如何提高SD card的读写速度
  • 音视频入门
  • 【LeetCode HOT 100】详细题解之二叉树篇
  • 汽车信息安全 -- 存到HSM中的密钥还需包裹吗?
  • some 蓝桥杯题
  • 不同版本的 Selenium 和 WebDriver 的 API 兼容性问题
  • cGANs with Projection Discriminator
  • Electron 使用 Nodemon 配置自动重启
  • PCL 点云高斯滤波
  • netty之基础aio,bio,nio
  • dcatadmin 自定义登录页面
  • webpack 和 vite 区别
  • 十一不停歇-学习ROS2第一天 (10.2 10:45)
  • Arduino UNO R3自学笔记18 之 Arduino的外部中断、定时中断介绍及应用