深度揭秘C++继承:理解面向对象编程的核心概念

一.继承

1.继承与面向对象

我们知道C语言是面向过程的编程语言,C++在C语言的基础上进化出了面向对象的模型。而继承就是面向对象的重要属性。继承使得我们在一个基础属性上能够加以拓展,用来描述很多具有相同基本属性又各有不同的事务。

2.继承方式访问权限

继承方式与访问权限相同都有三种:public、private、protected继承,再结合基类的三种访问权限,在派生类中就有九种不同的情况,可以总结为:基类为私有的成员在派生类一律不可见,其余权限按照与继承方式相比较小的来。

3.切片(赋值转换)

在实际应用场景中我们常用基类代表几种事务共同的基本属性,派生类用来代表自己独特的属性,这就会导致派生类对象一定是包含父类对象的,所以子类对象可以赋给父类对象/指针/引用,过程会将子类中独特属性的成员切出,剩余赋给父类对象,所以称为切片,不仅如此基类的指针可以通过强制类型转换赋值给派生类的指针,代码演示如下:

class Person
{
protected:
	string _name; 
	string _sex;
	int _age; 
};

class Student : public Person
{
public:
	int _No;
};

void Test()
{
	Student sobj;
	// 子类对象可以赋值给父类对象/指针/引用
	Person pobj = sobj;
	Person* pp = &sobj;
	Person& rp = sobj;


	// 基类的指针可以通过强制类型转换赋值给派生类的指针
	pp = &sobj;
	Student * ps1 = (Student*)pp; // 这种情况转换时可以的。
	ps1->_No = 10;

	pp = &pobj;
	Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问

	ps2->_No = 10;
}

int main()
{
	Test();
	return 0;
}

4.作用域

如果在基类和派生类定义了同名函数就会构成隐藏/重定义,子类成员将屏蔽父类对同名成员的直接访问,如下所示;

class A
{
public:
	A(int num = 0)
	:_num(num)
	{}

	void func()
	{
		cout << _num << endl;
	}
private:
	int _num;
};


class B : public A
{
public:
	B(int val = 1)
		:_val(val)
	{}

	void func()
	{
		cout << _val<< endl;
	}
private:
	int _val;
};

int main()
{
	B b;
	b.func();
	b.A::func();
	return 0;
}

5.默认成员函数

继承这里遵循着一个规则:构造先父后子,析构先子后父。因为派生类中一定包含基类的对象所以派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员,如果基类没有 默认
的构造函数
无参、全缺省、编译器默认生成),则必须在派生类构造函数的初始化列表阶段显示调用。
派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
派生类的operator=必须要调用基类的operator=完成基类的复制。
基类的析构函数调用后
会自动调用基类的析构函数
,不能在派生类显示调用不然无法保证析构先子后父的顺序。

6.友元与静态函数

友元关系不会继承,静态函数不会多次实例化。

7.解决菱形继承的二义性与数据冗余

菱形继承是多继承的一种特殊情况,我们在编写代码时应要避免菱形继承:
在这里插入图片描述
如上图所示就是一个菱形继承,这样会导致A类中会有两份P类中的成员,这样不仅会浪费空间,而且会产生二义性,如果我通过A对象访问P中的成员,因为A类中有两份P中的成员所有会有歧义。为了解决此问题,出现了虚拟继承。如下图所示:
在这里插入图片描述
那虚继承是如何完成的呢:在d类中建立虚基表,将原来冗余的对象放在d对象空间最下面,B、C原来存储A的位置存储当前位置与空间最下面A对象的偏移量,保证指定B或者C对象访问_a时都能访问到。

8.继承与组合

与继承相比组合的耦合度更低,更适合我们使用!继承又称为白箱复用,组合称为黑盒复用,因为使用组合的话是无法看到类内部的设计。
在这里插入图片描述

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论
C++是一种通用的高级编程语言,它支持面向对象编程和基于类的编程范式。下面是一些关于C++基础语法和面向对象编程的重要概念: 1. 数据类型:C++提供了多种数据类型,包括整数类型(int,long等),浮点数类型(float,double等),字符类型(char),布尔类型(bool)等。 2. 变量和常量:在C++中,可以使用关键字来声明和定义变量。变量是用于存储数据的容器,在使用之前需要先声明其类型。常量是不可修改的值,可以使用关键字const来声明。 3. 控制流语句:C++提供了多种控制流语句,包括条件语句(if-else语句,switch语句),循环语句(for循环,while循环,do-while循环)等。这些语句允许根据条件执行不同的代码块或者重复执行一段代码。 4. 函数:函数是完成特定任务的代码块,可以在程序中多次调用。C++中的函数可以有参数和返回值。函数的参数用于接收传入的值,返回值用于向调用者返回结果。 5. 数组:数组是一种用于存储相同类型数据的集合。在C++中,可以使用方括号([])来声明和访问数组。数组的元素可以通过索引进行访问,索引从0开始。 6. 类和对象:C++支持面向对象编程,其中类是一种自定义数据类型,用于封装数据和函数。类中的数据成员表示对象的属性,函数成员表示对象的行为。对象是类的实例,可以通过创建对象来访问类中的成员。 7. 继承和多态:C++中的继承允许一个类从另一个类派生,从而继承其属性和方法。派生类可以添加额外的属性和方法,也可以重写基类中的方法。多态性允许使用基类指针或引用来调用派生类的方法。 以上是C++基础语法和面向对象编程的一些重要概念。掌握这些概念可以帮助你编写更加灵活和可扩展的C++程序。如果你有具体的问题或者需要更深入的讨论,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aomnitrix

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值