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

C++面向对象——继承学习笔记

继承的基本语法

class 特殊的类 : public 公共的类
{

};

不用继承

  • 公共部分需要多次赋值粘贴,导致重复代码:
#include <iostream>  
using namespace std;  
class Java  
{  
public:  
    void header()  
    {  
        cout << "首页,公开课,登录,注册.....(公共头部)" << endl;  
    }  
  
    void footer()  
    {  
        cout << "帮助中心,交流合作,站内地图,....(公共底部)" << endl;  
    }  
  
    void left()  
    {  
        cout << "Java ,Python, c++, ....(公共信息列表)" << endl;  
    }  
  
    void content()  
    {  
        cout << "Java学科视频" << endl;  
    }  
};  
void test01()  
{  
    cout << "Java的下载页面如下" << endl;  
    Java ja;  
    ja.header();  
    ja.footer();  
    ja.left();  
    ja.content();  
}  
//Python页面  
class Python  
{  
  
};
- void test01()  
{  
    cout << "Java的下载页面如下" << endl;  
    Java ja;  
    ja.header();  
    ja.footer();  
    ja.left();  
    ja.content();  
}  
int main()  
{  
    test01();  
    return 0;  
}

  • 如果有新的每次都复制粘贴,现在用继承来写
//继承实现页面  
class BasePage  
{  
    //公共页面  
  
public:  
    void header()  
    {  
        cout << "首页,公开课,登录,注册.....(公共头部)" << endl;  
    }  
  
    void footer()  
    {  
        cout << "帮助中心,交流合作,站内地图,....(公共底部)" << endl;  
    }  
  
    void left()  
    {  
        cout << "Java ,Python, c++, ....(公共信息列表)" << endl;  
    }  
  
};  
//Java页面  
class Java : public BasePage  
{  
public:  
    void content()  
    {  
        cout << "java学科视频" << endl;  
    }  
};  
//Python页面  
class Python : public BasePage  
{  
public:  
    void content()  
    {  
        cout << "Python学科视频" << endl;  
    }  
};  
  
//C++页面  
class CPP : public BasePage  
{  
public:  
    void content()  
    {  
        cout << "C++学科视频" << endl;  
    }  
};  
  
void test01()  
{  
    cout << "Java的下载页面如下" << endl;  
    Java ja;  
    ja.header();  
    ja.footer();  
    ja.left();  
    ja.content();  
//此处省略了其他界面的调用
}
  • 综上,继承在开发中的优势就是减少重复代码

继承方式

  • 公共继承
  • 保护继承
  • 私有继承
  • 继承的规则:
  • public 继承,父类的成员访问权限是怎么样,到子类中还是怎么样
  • protected 继承,父类的公共和保护成员,到子类中变为了保护权限的变量
  • private 继承,父类的成员的公共和保护访问权限,到子类中全变为私有权限
  • 不论哪种继承方式,都不能访问父类中的私有权限的成员变量
  • 子类以私有继承的方式继承了父类的变量,然后孙子类又以公共权限继承它的父类。这种情况下,孙子类不能访问父类中的成员变量,因为它的父类在继承爷爷类的时候采取了私有继承,所以此时父类中的成员变量已经变为了私有权限,孙子类虽然以公共权限继承,但无法访问父类中的私有权限成员变量。

继承中的对象模型

  • 父类中的私有成员变量也会被子类继承,但是隐藏了。
  • 所以我们用sizeof来计算子类的大小时会包括父类的私有成员变量的大小
#include <iostream>
using namespace std;
class Base
{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};
class Son : public Base
{
public:

    int m_D;
};
void test01()
{
    //16
    //父类中的所有非静态成员属性都会被子类继承下去
    //父类中私有成员属性 是被编译器隐藏, 因此是访问不到的,但是确实被继承下去了
    cout << "size of Son = " << sizeof(Son) << endl;
}
int main()
{
    test01();
    return 0;
}
  • 最终的结果为
size of Son = 16

继承中的构造和析构顺序

#include <iostream>
using namespace std;
//继承中的构造和析构顺序
class Base
{
public:
    Base()
    {
        cout << "Base构造函数 " << endl;
    }
    ~Base()
    {
        cout << "Base的析构函数" << endl;
    }
};
class Son:public Base
{
public:
    Son()
    {
        cout << "Son的构造函数" << endl;
    }

    ~Son()
    {
        cout << "Son的析构函数" << endl;
    }
};
void test01()
{
    //Base b;
    Son s1;

}
int main()
{
    test01();
    system("pause");
    return 0;
}

  • 运行结果
Base构造函数 
Son的构造函数
Son的析构函数
Base的析构函数
  • 继承中的构造和析构顺序如下:
    先构造父类在构造子类,析构的顺序与构造的顺序相反

同名成员处理

  • 在访问子类和父类的同名成员变量时,通过子类对象访问父类成员需要加作用域才能访问,否则默认访问的是子类中的成员变量

多继承

  • 语法: class 子类 : 继承方式 父类1, 继承方式 父类2…
  • 当父类中出现同名成员需要加作用域区分
#include <iostream>  
using namespace std;  
class Base1  
{  
public:  
    Base1()  
    {  
        m_A = 100;  
    }  
    int m_A;  
};  
  
class Base2  
{  
public:  
    Base2()  
    {  
        m_A = 200;  
    }  
    int m_A;  
};  
//子类 需要继承Base1和Base2  
//语法: class 子类 : 继承方式 父类1, 继承方式 父类2...  
class Son : public Base1, public Base2  
{  
public:  
    Son()  
    {  
        m_C = 300;  
        m_D = 400;  
    }  
    int m_C;  
    int m_D;  
};  
void test01()  
{  
    Son s;  
  
    cout << "sizeof Son = " << sizeof (Son) << endl;  
    //当父类中出现同名成员需要加作用域区分  
    cout << "Base1 : m_A = " << s.Base1::m_A << endl;  
    cout << "Base2 : m_A = " << s.Base2::m_A << endl;  
}  
int main()  
{  
    test01();  
    return 0;  
}

菱形继承

  • 利用虚继承,解决菱形继承问题
  • 继承之前加上关键字virtual 变为虚继承
  • Animal类称为虚基类
#include <iostream>  
using namespace std;  
//动物类  
class Animal  
{  
public:  
    int m_Age;  
};  
  
//利用虚继承,解决菱形继承问题  
//继承之前加上关键字virtual 变为虚继承  
//Animal类称为虚基类  
//羊类  
class Sheep : virtual public Animal{};  
class Tuo : public virtual Animal{};  
class SheepTuo : public Sheep, public Tuo{};  
void test01()  
{  
    SheepTuo st;  
  
    st.Sheep::m_Age = 18;  
    st.Tuo::m_Age = 27;  
  
    //当菱形继承的时候, 两个父类拥有相同的数据,需要加以作用域区分  
    cout << "st.Sheep::m_Age" << st.Sheep::m_Age << endl;  
    cout << "st.Tuo::m_Age" << st.Tuo::m_Age << endl;  
    cout << "st.m_Age = " << st.m_Age << endl;  
  
    //这份数据我们 知道有一份, 菱形继承导致资源浪费  
}  
int main()  
{  
    test01();  
    return 0;  
}

相关文章:

  • 用AI写小说-小白写小说的第一步Prompt
  • HTML中修改标题和段落的第三种方式——外部样式表
  • 【安卓逆向】安卓病毒介绍及其简单案例分析
  • 解决VMware虚拟机CentOS 7 忘记登陆密码问题
  • API接口安全中的数据加密实践:原理与实现详解
  • 【Java】——数据类型和变量
  • JAVA代码块
  • visual studio配置opencv
  • 【后端开发面试题】每日 3 题(十一)
  • 【linux】解决 Linux 系统中 root 用户无法打开图形界面问题
  • Python 的字符串格式化方法
  • 编程助手学Python--Deepseek对OpenAI的Python库调用GPT-4模型生成对话回复理解
  • docker 常用命令大全(二),docker 镜像操作 ,持续更新
  • 仅仅使用pytorch来手撕transformer架构(1):位置编码的类的实现和向前传播
  • 系统架构设计师知识小科普:系统架构评估
  • 【文献阅读】SPRec:用自我博弈打破大语言模型推荐的“同质化”困境
  • Linux上位机开发实战(qt编译之谜)
  • vue 仿deepseek前端开发一个对话界面
  • 3分钟复现 Manus 超强开源项目 OpenManus
  • 使用netlify部署github的vue/react项目或本地的dist,国内也可以正常访问
  • 2024年上市公司合计实现营业收入71.98万亿元
  • 顾家家居:拟定增募资近20亿元,用于家居产品生产线的改造和扩建等
  • 深入贯彻中央八项规定精神学习教育中央第六指导组指导督导中国工商银行见面会召开
  • 上海“随申兑”服务平台有哪些功能?已归集800余个惠企政策
  • 巴国家安全委员会授权军方自主决定对印反击措施
  • 8大类1000多支,中国红十字会已建成10万人规模救援队伍