c++ -- 继承和派生

学习资源来源于中国慕课

继承

定义: 在已经定义了一个类A之后,再定义一个类B,并且类B有类A的所有成员(包括成员函数和成员变量),那么类A就叫做基类,类B叫做派生类,也称为子类。简单说来,就相当于类B是在类A上的扩张定义。但两者时独立的关系,可以独立使用。
示例
在这里插入图片描述
概括所有事物的共同特点,写一个基类。然后为 每种事物写一个类,都从基类派生而来。而派生类的写法是:类名: public 基类名如class B:public A

派生类对象的内存空间
派生类对象的体积,等于基类对象的体积,再加上派 生类对象自己的成员变量的体积。在派生类对象中,包含着基类对象,而且基类对象的存储位置位于派生类对象新增的成员变量之前。
在这里插入图片描述
示例2

#include<iostream>
#include<iomanip>
using namespace std;
class student {
private:
	string name;
public:
	student() { name ="casv"; }
	void setname(const string& _name) { name = _name; }
	string GetName() { return name; }
	void PrintInfo() {
		cout <<"Name:"<< GetName() << endl;
	}
};
class UnderGrateStudent :public student {
private:
	string department = "vsdv";
public:
	void QualifiedForBaoYan() { cout << "有保研资格" << endl; }
	void PrintInfo() {
		student::PrintInfo();//第一个类的函数
		cout << "department:"<< department << endl;
		QualifiedForBaoYan();
	}
};
class UnderStudent :public student {
private:
	int department = 123;
	char MentorName[20] = "scs";
public:
	void PrintInfo() {
		student::PrintInfo();//第一个类的函数
		cout << "department:" << department << " MentorName:" << MentorName << endl;
	}
};
int main()
{
	student s1;
	s1.setname("aa");
	s1.PrintInfo();
	UnderGrateStudent s2;
	s2.setname("bb");
	s2.PrintInfo();
	UnderStudent s3;
	s3.setname("cc");
	s3.PrintInfo();
	return 0;
}

执行效果
在这里插入图片描述


继承关系和复合关系

类之间的两种关系
在这里插入图片描述
如几何形体程序中,需要写“点”类,也需要写“圆”类,两 者的关系就是复合关系 ---- 每一个“圆”对象里都包含 (有)一个“点”对象,这个“点”对象就是圆心

class CCircle;
class CPoint {
	double x,y; 
	friend class CCircle;//便于Ccirle类操作其圆心
};

class CCircle {
	double r; 
	CPoint center;
};

在这里插入图片描述


复合关系讨论

如果一个很优秀的人在北京有十套房子,那么如何写类呢?(房子与人的关系)

  1. 此定义是循环定义,不正确
class human;
class house {//一套房子的主人
	human a;
};
class human {//一个人有十套房子
	house home[10];
};
  1. 为“房子”类设一个“人”类的成员对象; 为“人”类设一个“房子”类的对象指针数组。但是修改10个房子的主任,需要修改十次,太重复了。
class human;
class house {
	human a;
};
class human {
	house *home[10];
};
  1. 为“人”类设一个“房子”类的成员对象数组; 为“房子”类设一个“房子”类的对象指针.如此,每一个房子都指向同一个人。
class human;
class house {
	human *a;//指向同一个人
};
class human {
	house home[10];
};
  1. 最好的方式是
class human;
class house {
	human *a;
};
class human {
	house *home[10];
};

派生类覆盖基类成员

派生类可以定义一个和基类成员同名的成员,这叫 覆盖。在派生类中访问这类成员时,缺省的情况是 访问派生类中定义的成员。要在派生类中访问由基 类定义的同名成员时,要使用作用域符号::。
在这里插入图片描述
一般来说,基类和派生类不定义同名成员变量。


类的保护成员

三种类型总结
在这里插入图片描述
在这里插入图片描述


派生类的构造函数

  1. 在创建派生类的对象时,需要调用基类的构造函数:初始化派 生类对象中从基类继承的成员。在执行一个派生类的构造函数 之前,总是先执行基类的构造函数。
  2. 调用基类构造函数的两种方式
    – 显式方式:在派生类的构造函数中,为基类的构造函数提供参数
    – 隐式方式:在派生类的构造函数中,省略基类构造函数时, 派生类的构造函数则自动调用基类的默认构造函数.
  3. 派生类的析构函数被执行时,执行完派生类的析构函数后,自 动调用基类的析构函数。因为基类的内部, 有一些是派生类不了解的. 为了方便,为了安全,为了管理. 所以派生类的对象销毁的时候, 继承机制会分级调用各级的析构函数。
#include<iostream>
#include<iomanip>
using namespace std;
class A {
private:
	int leg;
	int color;
public:
	int type;
	A(int _leg, int _color);
	void print() {
		cout <<"leg:"<< leg << "  color:" << color << "  " << endl;
	}
};
class B :public A {
private:
	int wing;
public:
	B(int _leg, int _color, int _wing);
	void print() {
		A::print();
		cout << "wing:" << wing << "  type:" << type << endl;
	}
};
A::A(int _leg, int _color) {
	leg = _leg;
	color = _color;
}
B::B(int _leg, int _color, int _wing) :A(_leg, _color) {
	wing = _wing;
}
int main()
{
	B a(1, 2, 3);
	a.type = 1;
	a.print();
	return 0;
}

执行效果
在这里插入图片描述
函数执行顺序判断:在执行一个派生类的构造函数 之前,总是先执行基类的构造函数。派生类的析构函数被执行时,执行完派生类的析构函数后,自 动调用基类的析构函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


public继承的赋值兼容规则

在这里插入图片描述
注意:如果派生方式是 private或protected,则上述三条不可行。
在这里插入图片描述
基类与派生类的指针强制转换
在这里插入图片描述


直接基类和间接基类

在这里插入图片描述

#include<iostream>
#include<iomanip>
using namespace std;
#include <iostream> using namespace std; 
class Base { 
	public:
	int n; 
	Base(int i) :n(i){}
	~Base() { cout << "Base " << n << " destructed" << endl; }
};
class Derived :public Base {
public:
	Derived(int i) :Base(i) {
		cout << "Derived constructed" << endl;
	}
	~Derived() {
		cout << "Derived destructed" << endl;
	}
};
class MoreDerived :public Derived {
public:
	MoreDerived() :Derived(4) { cout << "More Derived constructed" << endl;}
	~MoreDerived() { cout << "More Derived destructed" << endl; }
};
int main() {
	MoreDerived Obj; 
	return 0;
}

执行效果
在这里插入图片描述

发布了166 篇原创文章 · 获赞 45 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/104183231