C++继承和派生

本文详细介绍了C++中的继承和派生概念,包括继承的4种特性、类之间的关系、继承方式(public、private、protected)及其影响、派生类的访问控制原则、构造和析构函数在继承中的应用,以及虚继承解决的二义性问题。通过对继承的深入理解,可以更好地实现代码复用和面向对象的设计。

在这里插入图片描述

1 继承概念

面向对象程序设计有4个主要特点:**抽象、封装、继承和多态性。**我们已经讲解了类和对象,了解了面向对象程序设计的两个重要特征一数据抽象与封装,已经能够设计出基于对象的程序,这是面向对象程序设计的基础。要较好地进行面向对象程序设计,还必须了解面向对象程序设计另外两个重要特征——继承性和多态性。这个文章主要介绍有关继承的相关知识,多态性将在后续文章当中讲解。
继承性是面向对象程序设计最重要的特征,可以说,如果没有掌握继承性,就等于没有掌握类和对象的精华,就是没有掌握面向对象程序设计的真谛。

1 类之间的关系
  • 包含关系:B has A==>类B依赖于类A谁包含谁,谁就依赖于谁,因为类A的对象要先于类B创建,等类A对象创建完才能完成类B对象的创建,所以类B依赖于类A.
class B
{
   
   
public:
private:
    A a;//当对象A不存在无参构造函数时,需要显示的写出初始化函数列表
};

  • 类A是类C成员方法的形参,即C use A//类C依赖于类A,但耦合度类C明显低于类B
class C
{
   
   
public:
    void funcC(A a)
    {
   
   
    }
private:
};
  • 类D继承于A,D是A的子类,A的代码都存在于类D的内部,即B is A//类D依赖于类A,继承的耦合度是极高的,但可以增加代码的重复使用.
class D:public A
{
   
   
public:

private:
};

程序追求的最高境界是;高内聚(函数功能越单一越好,目标越专一越好),低耦合(类与其他类关系越少越好)

2 继承关系举例

下面我们举几个栗子来具体说明继承的概念
在这里插入图片描述
在这里插入图片描述

4 派生类的定义

在这里插入图片描述
注意:C++中的继承方式(public、private、protected)会影响子类的对外访问属性。

5 继承重要说明
  1. 子类拥有父类的所有成员变量和成员函数(理解儿子继承父亲的家产)
  2. 子类可以拥有父类没有的方法和属性(儿子可以青出于蓝)
  3. 子类就是一种特殊的父类
  4. 子类对象可以当作父类对象使用

2 派生类的访问控制

派生类(子类)继承了基类(父类)的全部成员变量和成员方法**(除了构造和析构之外的成员方法),但是这些成员的访问属性,在派生过程中是可以调整**的。(比如父类有一个私有成员为情人,子类继承了父亲的全部成员,但是这个时候是不能访问父类的情人的…)

1 单个类的访问控制

1 类成员访问级别(public、private、protected)

  • private: 只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问.
  • protected: 可以被该类中的函数、子类的函数、以及其友元函数访问,但不能被该类的对象访问
  • public: 可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
    注:友元函数包括两种:设为友元的全局函数,设为友元类中的成员函数
2 不同的继承方式会改变继承成员的访问属性

不同的继承方式会改变继承成员的访问属性
public继承:父类成员在子类中保持原有访问级别(最常用的方法)
private继承:父类成员在子类中变为private成员
protected继承:父类中public成员会变成protected(这一点和public继承不同)
父类中protected成员仍然为protected
父类中private成员仍然为private

private成员在子类中依然存在,但是却无法访问到。不论种方式继承基类,派生类都不能直接使用基类的私有成员 。
C++中子类对外访问属性表
|  |  ||--|--||  |  |

3 判断成员是否可以被访问原则

C++中的继承方式(public、private、protected)会影响子类的对外访问属性
判断某一句话,能否被访问。

  1. 看调用语句,这句话写在子类的内部、外部
  2. 看子类如何从父类继承(public、private、protected)
### C++继承派生的概念 继承派生是面向对象编程的核心机制之一,允许一个类(派生类)基于另一个类(基类)定义其属性行为。这种机制使得派生类不仅可以复用基类的成员,还可以扩展或修改其功能,从而实现代码的重用层次化设计[^1]。 继承体现了类型之间的“是一种”关系(is-a),例如“狗是一种动物”。派生类在继承基类成员的基础上,可以添加新的成员变量成员函数,以表达更具体的行为状态[^2]。 ### 使用方法 C++ 中的继承通过在类定义中使用冒号 `:` 指定基类,并可选择继承方式(`public`、`protected` 或 `private`)。最常见的是公有继承(`public`),它使得基类的公有成员在派生类中仍为公有,保护成员变为保护成员,而私有成员不可访问。 派生类构造函数需要显式调用基类构造函数以初始化继承的成员。如果未显式调用,编译器会尝试调用基类的默认构造函数。若基类没有默认构造函数,则会导致编译错误。 派生类可以访问基类的公有保护成员,但不能直接访问私有成员。此外,派生类可以重写基类的虚函数以实现多态行为。 ### 示例 以下是一个简单的继承派生示例,展示如何定义基类派生类,并调用其成员函数: ```cpp #include <iostream> using namespace std; // 基类 class Animal { public: virtual void speak() const { cout << "Animal speaks" << endl; } }; // 派生类 class Dog : public Animal { public: void speak() const override { cout << "Woof!" << endl; } }; int main() { Dog myDog; myDog.speak(); // 输出 "Woof!" return 0; } ``` 在这个例子中,`Dog` 类公有继承了 `Animal` 类,并重写了 `speak()` 函数以实现不同的行为。由于 `speak()` 是虚函数,因此可以通过基类指针或引用调用派生类的实现,实现多态性。 ### 构造函数与析构函数的调用顺序 派生类的构造函数必须负责调用基类的构造函数来初始化继承的成员。例如: ```cpp class Base { public: Base(int x) { cout << "Base constructor called with " << x << endl; } }; class Derived : public Base { public: Derived(int x, int y) : Base(x) { cout << "Derived constructor called with " << y << endl; } }; ``` 当创建 `Derived` 对象时,首先调用 `Base` 的构造函数,然后执行 `Derived` 的构造函数体。析构过程则相反,先析构派生类,再析构基类。 ### 静态成员的继承 静态成员函数静态变量在派生类中是共享的,它们属于类本身而不是对象。例如: ```cpp class Base { public: static void info() { cout << "Base static info" << endl; } }; class Derived : public Base {}; int main() { Derived::info(); // 调用 Base 的静态函数 return 0; } ``` 如果派生类定义了同名的静态函数,则会隐藏基类的版本,但可以通过作用域解析运算符访问: ```cpp class Derived : public Base { public: static void info() { cout << "Derived static info" << endl; } }; int main() { Derived::info(); // 输出 "Derived static info" Base::info(); // 输出 "Base static info" return 0; } ``` ### 内存布局 派生类的内存布局包括基类的成员派生类新增的成员。基类的成员位于派生类对象内存的低地址部分,新增成员位于高地址部分。无论继承多少层,静态成员函数变量在整个程序中只有一份副本,存放在静态存储区[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值