前言
继承是面向对象编程的一大特色,既是重点也是难点,本文收录了我在学习C++语言继承的知识点。
继承
单继承
说到继承,不得不提继承方式与子类对象的访问权限之间的关系。具体关系详见下表。
代码示例如下:
#include <iostream>
using namespace std;
class People {
private:
int money;
protected:
char name[12];
public:
int age;
int weight;
};
class Student : public People {
public:
int number;
int score;
void print() {
cout << name << weight << endl;
}
};
int main()
{
Student s;
s.age = 10;
return 0;
}
函数隐藏
先上定义:
如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名(只要函数名相同),那么就会隐藏从基类继承过来的成员。就是在派生类中使用该成员,实际上使用的是派生类新增的成员,而不是从基类继承来的。
个人理解:
本人更愿意理解成覆盖,即子类声明的函数覆盖了父类的函数。
#include <iostream>
using namespace std;
class People {
private:
int money;
protected:
char name[12];
public:
int age;
int weight;
void print() {
cout << "People" << endl;
}
};
class Student : public People {
public:
int number;
int score;
void print() {
cout << "Student" << endl;
}
};
int main()
{
Student s;
s.print();
return 0;
}
运行结果如下:
如果我们想访问父类的函数可以通过如下方式:
s.People :: print();
基类和派生类的构造析构顺序
代码如下:
#include <iostream>
using namespace std;
class People {
public:
People(){
cout << "People" << endl;
}
~People() {
cout << "~People" << endl;
}
};
class Student : public People {
public:
Student() {
cout << "Student" << endl;
}
~Student() {
cout << "~Student" << endl;
}
};
int main()
{
Student s;
return 0;
}
运行结果如下:
通过运行结果我们可以知道声明子类对象时构造和析构的顺序:父类构造->子类构造->子类析构->父类析构。
多继承
代码如下:
#include <iostream>
using namespace std;
class People {
protected:
int age;
public:
void doWork() {
cout << "吃饭 睡觉" << endl;
}
};
class Worker : public People {
public:
void doWork2() {
cout << "搬砖" << endl;
}
};
class Farmer : public People {
public:
void doWork3() {
cout << "种地" << endl;
}
};
class MigrantWorker : public Worker, public Farmer {
};
int main()
{
MigrantWorker mw;
mw.People :: doWork();
mw.doWork2();
mw.doWork3();
return 0;
}
虚继承
由来:
我们刚刚看过多继承,如果使用多继承就会出现从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题。详细的说就是:假如我们有类A是父类,类B和类C继承了类A,而类D既继承类B又继承类C(这种菱形继承关系)。 当我们实例化D的对象的时候,每个D的实例化对象中都有了两·份完全相同的A的数据。如果还不懂就看这张图:
如果我们使用虚继承,这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样不仅就解决了二义性问题,也节省了内存,避免了数据不一致的问题。
声明虚继承在继承的时候在父类前面加上virtual即可。
代码示例如下:
class Worker : virtual public People {
public:
void doWork2() {
cout << "搬砖" << endl;
}
};
class Farmer : virtual public People {
public:
void doWork3() {
cout << "种地" << endl;
}
};
class MigrantWorker : virtual public Worker, virtual public Farmer {
};
虚继承介绍部分内容转载于该博客: C++虚继承的概念[转].