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

C++之类的继承与派生

一,继承与派生相关概念

  • 保持已有类的特性而构造新类的过程称为继承
  • 在已有类的基础上新增自己的特性而产生新类的过程称为派生
  • 被继承的已有类称为基类(或父类)
  • 派生出的新类称为派生类(或子类)

继承与派生问题举例:

二,继承与派生的目的

  • 继承的目的:实现代码重用、提高扩展性。
  • 派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。

派生类的声明

class 派生类名 : 继承方式  基类名
{        
成员声明;
};

继承方式

不同继承方式的影响主要体现在:

  • 派生类成员对基类成员的访问权限
  • 通过派生类对象对基类成员的访问权限

三种继承方式:

  • 公有继承
  • 私有继承
  • 保护继承

三,公有继承(public)

类内部:

  • 基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。
  • 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。

类外部:

  • 通过派生类的对象只能访问基类的public成员。

公有继承举例:

#include <iostream>
using namespace std;//父类
class A
{
public:void fun_A_public(){cout << "A::fun_A_public()" << endl;}protected:void fun_A_protected(){cout << "A::fun_A_protected()" << endl;}private:void fun_A_private(){cout << "A::fun_A_private()" << endl;}
};//子类(public继承)
class B : public A
{
public:void fun_B_public(){cout << "B::fun_B_public()" << endl;}protected:void fun_B_protected(){cout << "B::fun_B_protected()" << endl;}private:void fun_B_private(){cout << "B::fun_B_private()" << endl;}public:// 测试函数:在子类内部访问父类成员void test_in_class(){cout << "子类内部访问父类成员" << endl;fun_A_public();      //可访问(public)fun_A_protected();   //可访问(protected)// fun_A_private();  //无法访问(private)}
};int main()
{B b;cout << "--- 子类对象访问父类成员 ---" << endl;b.fun_A_public();     //可访问(public)// b.fun_A_protected(); //无法访问(protected)// b.fun_A_private();   //无法访问(private)cout << "--- 子类对象访问子类成员 ---" << endl;b.fun_B_public();     //可访问// b.fun_B_protected(); //无法访问// b.fun_B_private();   //无法访问cout << endl;b.test_in_class();    // 测试在子类内部访问父类成员return 0;
}

运行结果:

程序详解:

四,保护继承(protected)

类内部:

  • 基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可直接访问。
  • 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。

类外部:

  • 通过派生类的对象不能直接访问基类中的任何成员。

保护继承举例:

#include <iostream>
using namespace std;//父类
class A
{
public:void fun_A_public(){cout << "A::fun_A_public()" << endl;}protected:void fun_A_protected(){cout << "A::fun_A_protected()" << endl;}private:void fun_A_private(){cout << "A::fun_A_private()" << endl;}public:// 测试:类A内部访问自身成员void test_in_A(){cout << "--- 类A内部访问自身成员 ---" << endl;fun_A_public();      //可访问fun_A_protected();   //可访问fun_A_private();     //可访问}
};//子类(protected继承)
class B : protected A
{
public:void fun_B_public(){cout << "B::fun_B_public()" << endl;}protected:void fun_B_protected(){cout << "B::fun_B_protected()" << endl;}private:void fun_B_private(){cout << "B::fun_B_private()" << endl;}public:// 测试:在子类内部访问父类成员void test_in_B(){cout << "--- 子类B内部访问父类A成员 ---" << endl;fun_A_public();      //可以访问(public 在 protected继承后变为 protected)fun_A_protected();   //可以访问(protected 保持为 protected)// fun_A_private();  //无法访问(private 无法继承)}
};//外部测试
int main()
{A a;B b;cout << "--- 类A对象外部访问 ---" << endl;a.fun_A_public();        //可访问(public)// a.fun_A_protected();  //无法访问// a.fun_A_private();    //无法访问cout << endl;a.test_in_A();           //类A内部测试cout << endl;b.test_in_B();           //子类内部访问测试cout << endl;cout << "--- 类B对象外部访问 ---" << endl;// b.fun_A_public();     //无法访问(public 继承变为 protected)// b.fun_A_protected();  //无法访问(protected)b.fun_B_public();        //可以访问(B自己的public)// b.fun_B_protected();  //无法访问(protected)// b.fun_B_private();    //无法访问(private)return 0;
}

运行结果:

程序详解:

五,私有继承(private)

类内部:

  • 基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。
  • 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。

类外部:

  • 通过派生类的对象不能直接访问基类中的任何成员。

私有继承举例:

#include <iostream>
using namespace std;//父类
class A
{
public:void fun_A_public(){cout << "A::fun_A_public()" << endl;}protected:void fun_A_protected(){cout << "A::fun_A_protected()" << endl;}private:void fun_A_private(){cout << "A::fun_A_private()" << endl;}public:// 测试:类A内部访问自身成员void test_in_A(){cout << "--- 类A内部访问自身成员 ---" << endl;fun_A_public();      //可访问fun_A_protected();   //可访问fun_A_private();     //可访问}
};//子类(private继承)
class B : private A
{
public:void fun_B_public(){cout << "B::fun_B_public()" << endl;}protected:void fun_B_protected(){cout << "B::fun_B_protected()" << endl;}private:void fun_B_private(){cout << "B::fun_B_private()" << endl;}public:// 测试:在子类内部访问父类成员void test_in_B(){cout << "--- 子类B内部访问父类A成员 ---" << endl;fun_A_public();      //可访问(但在B中变为private)fun_A_protected();   // 可访问(但在B中变为private)// fun_A_private();  //无法访问(private成员不可继承)}
};//外部测试
int main()
{A a;B b;cout << "--- 类A对象外部访问 ---" << endl;a.fun_A_public();        //可访问(public)// a.fun_A_protected();  //无法访问// a.fun_A_private();    //无法访问cout << endl;a.test_in_A();           //类A内部测试cout << endl;b.test_in_B();           //子类内部访问测试cout << endl;cout << "--- 类B对象外部访问 ---" << endl;// b.fun_A_public();     //无法访问(在B中变为private)// b.fun_A_protected();  // 无法访问(在B中变为private)b.fun_B_public();        //可访问(B自己的public)// b.fun_B_protected();  //无法访问// b.fun_B_private();    //无法访问return 0;
}

运行结果:

程序详解:

六,继承访问总结

继承的本质是子类复用父类的代码。而继承方式 (public, protected, private) 则像一个“权限控制器”,它决定了父类的成员(主要是 public 和 protected 成员)被子类继承后,在子类中拥有什么样的访问权限。

1、 两条基本原则

  1. 子类内部访问:无论采用哪种继承方式,在子类的内部(其成员函数中),都可以直接访问父类的 public 和 protected 成员。这与继承方式无关,是继承的基本特性。

  2. 父类 private 成员的绝对性:父类的 private 成员对于子类来说永远是不可见的,子类无法以任何方式直接访问。这一点不受继承方式的影响。

2、 三种继承方式的权限变化规则

继承方式决定了父类成员在子类中的最终访问权限。这个最终权限取决于两个因素的最小值

  1. 成员在父类中的原始权限 (public > protected > private)。

  2. 继承方式的权限 (public > protected > private)。

权限取小原则:最终权限 = min(父类成员权限, 继承方式)

下面是具体的规则和总结表:

  • 规则:父类的成员权限保持不变地继承下来。

    • 父类的 public 成员 -> 在子类中依然是 public。

    • 父类的 protected 成员 -> 在子类中依然是 protected。

  • 目的:实现 "is-a" 的关系,保持父类的公有接口在子类中仍然是公有的。

  • 规则:将父类中更开放的 public 权限收缩为 protected。

    • 父类的 public 成员 -> 在子类中变为 protected。

    • 父类的 protected 成员 -> 在子类中依然是 protected。

  • 目的:不希望父类的公有接口被外界(类外部)直接访问,但希望在后续的继承链中可以被继续继承和访问。

  • 规则:将父类的所有可访问成员全部收缩为 private。

    • 父类的 public 成员 -> 在子类中变为 private。

    • 父类的 protected 成员 -> 在子类中变为 private。

  • 目的:实现 "is-implemented-in-terms-of" 的关系,即子类仅仅是想复用父类的代码实现,而不希望父类的任何接口(无论是公有的还是保护的)对外暴露或被进一步继承。

3、 权限变化总结表

这张表清晰地展示了“权限取小”的规则:

继承方式父类 public 成员父类 protected 成员父类 private 成员
public 继承在子类中变为 public在子类中变为 protected在子类中不可访问
protected 继承在子类中变为 protected在子类中变为 protected在子类中不可访问
private 继承在子类中变为 private在子类中变为 private在子类中不可访问

4、 类外部访问

  • 类外部(例如 main 函数)只能通过对象访问其 public 成员。

  • 因此,只有在**public继承**下,父类的public成员才能通过子类对象在类外部被访问。

  • 在 protected 和 private 继承下,父类的所有成员在子类中都变成了 protected 或 private,所以无法通过子类对象从外部访问

5、图示

http://www.dtcms.com/a/461905.html

相关文章:

  • Yudao单体项目 springboot Admin安全验证开启
  • 电子商务网站建设风格网站建设技术的实现
  • 【Frida Android】基础篇2:Frida基础操作模式详解
  • 应用于ElasticSearch的C++ API——elasticlient
  • MyISAM存储引擎的特点
  • 伺服滑差补偿方案
  • 无锡网站建设排名安徽网站开发建设
  • 【C++】探秘string的底层实现
  • 建设卡开通网银网站学做网站 空间 域名
  • 基于Simulink的太阳能单极性移相控制光伏并网逆变器
  • 受欢迎的锦州网站建设wordpress取消默认图片
  • CUDA-Q Quake 规范详解:量子中间表示的技术深度解析
  • 包头教育平台网站建设吉化北建公司官网
  • LeetCode 3494.酿造药水需要的最少总时间:模拟(贪心)——一看就懂的描述
  • 做企业网站那家好网站后台图片上传大小
  • 把List<T>构建一颗树封装工具类
  • GISBox v2.0.0:新增功能、问题修复、性能优化三维度,强化GIS服务核心能力
  • Qt界面布局利器:QStackedWidget详细用法解析
  • ClickHouse 配置优化与问题解决
  • 宁波网站建设果核个人网页制作教程简单
  • 白塔网站建设iis .htaccess wordpress
  • 【计算机视觉】基于复杂环境下的车牌识别
  • 域名会跳转怎么进原网站wordpress注册没用
  • YOLO26 详解:面向边缘与低功耗的端到端(NMS‑free)目标检测新范式
  • 仿win8网站建电子商务网站需要多少钱
  • 网站右下角视频代码网站免费下载安装
  • 《低压配电数字化转型实战指南》13: 技术创新:下一代配电技术探索
  • 再见的数字怎么说好听
  • Cesium 军事标绘入门:用 Cesium-Plot-JS 快速实现标绘功能
  • 【ROS2快速学习】