【C++】继承入门

继承入门

  • 1. 继承的概念及定义
    • 1.1 继承的概念
    • 1.2 继承的定义
  • 2. 父子类间赋值转换
    • 2.1 父类指针 指向 子类对象
    • 2.2 父类指针 强转赋值给 子类指针
    • 3.2 父类对象 不能赋值给 子类
  • 4. 子类的默认含有的成员函数
  • 5. 菱形继承
    • 5.1 菱形继承的概念
    • 5.2 菱形继承的问题
    • 5.3 解决菱形继承问题的方法--->虚拟继承
  • 6. 继承总结

1. 继承的概念及定义

1.1 继承的概念

  • 继承(inheritance)机制是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生的新类称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。

1.2 继承的定义

【定义格式】

Person是父类,也称作基类。

Student是子类,也称作派生类。

【C++】继承入门_第1张图片

【继承关系与访问限定符】

【C++】继承入门_第2张图片

【不同继承方式下的成员访问属性】

【C++】继承入门_第3张图片

2. 父子类间赋值转换

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

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

2.1 父类指针 指向 子类对象

Student sobj;

Person pobj = sobj;		// 子类对象 赋值给 父类对象
Person* pp = &sobj;		// 子类对象 赋值给 父类指针
Person& rp = sobj;		// 子类对象 赋值给 父类引用

2.2 父类指针 强转赋值给 子类指针

Student* ps1 = (Student*)new Person();	// 访问可能会越界

3.2 父类对象 不能赋值给 子类

Student sobj;
Person pobj = sobj;

sobj = pobj;

4. 子类的默认含有的成员函数

【C++】继承入门_第4张图片

5. 菱形继承

5.1 菱形继承的概念

【单继承】:一个子类只有一个直接父类时,称这个继承关系为单继承

【C++】继承入门_第5张图片

【多继承】:一个子类有两个或以上直接父类时,称这个继承关系为多继承

【C++】继承入门_第6张图片

【菱形继承】:菱形继承是多继承的一种特殊情况

【C++】继承入门_第7张图片

5.2 菱形继承的问题

  • 菱形继承的问题:从下面的成员模型可以看出菱形继承数据冗余二义性的问题

数据冗余:Assistant类中将_name和_num保存了两份

二义性:由于_name保存了两份,Assistant类的_name就无法被唯一确定

【C++】继承入门_第8张图片

5.3 解决菱形继承问题的方法—>虚拟继承

使用作用域运算符可以解决菱形继承中数据二义性的问题,但是无法解决数据冗余的问题

Assistant a;

// 这样会有二义性无法明确知道访问的是哪一个
a._name = "peter";

// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
a.Student::_name = "xxx";
a.Teacher::_name = "yyy";

使用 虚拟继承 既可以解决数据二义性问题,也可以解决数据冗余问题

class A
{
     
public:
	int _a;
};

// class B : public A
class B : virtual public A
{
     
public:
	int _b;
};

// class C : public A
class C : virtual public A
{
     
public:
	int _c;
};

class D : public B, public C
{
     
public:
	int _d;
};

int main()
{
     
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;

    cout << "d.B::_a : " << &(d.B::_a) << endl;
	cout << "d.C::_a : " << &(d.C::_a) << endl;
	cout << "d._b    : " << &(d._b) << endl;
	cout << "d._c    : " << &(d._c) << endl;
	cout << "d._d    : " << &(d._d) << endl;
    
	return 0;
}

【虚拟继承数据成员模型】

【C++】继承入门_第9张图片

6. 继承总结

  1. 使用单继承,避免使用多继承
  2. public继承是一种 is - a 的关系,代码耦合度高,这种复用称为白箱复用
  3. 数据成员和类之间是一种 has - a 的关系,代码耦合度低,这种复用称为黑箱复用
  4. 优先使用对象组合,而不是类继承
// Car和BMW Car和Benz构成is-a的关系
class Car{
     };
class BMW : public Car{
      };
class Benz : public Car{
      };
// Tire和Car构成has-a的关系
class Tire{
     };
class Car{
     
protected:
	Tire _t; // 轮胎
};

你可能感兴趣的:(#,C++语法,类,c++,继承,菱形继承)