继承
定义:继承就是新类从已有类那里得到已有的特性。类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类,产生的新类称为派生类或子类。
继承可以扩展已存在的代码,目的也是为了代码重用,继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。其权限如下图所示:
下面是一个时钟的例子。
#include <iostream>
using namespace std;
class Clock
{
public:
Clock(int h = 0, int m = 0, int s = 0) : hour(h), minute(m), second(s)
{
cout << "This is the Clock's constructor" << endl;
}
Clock(const Clock &other) : hour(other.hour), minute(other.minute), second(other.second)
{
cout << "This is the Clock's copy constructor" << endl;
}
~Clock()
{
cout << "This is the Clock's destructor" << endl;
}
void showTime()
{
cout << hour << ":" << minute << ":" << second << endl;
}
void setTime(int h, int m, int s)
{
hour = h;
minute = m;
second = s;
}
private:
int hour;
int minute;
int second;
};
class CalendarClock : public Clock
{
public:
CalendarClock(int y, int M, int d, int h, int m, int s) : Clock(h, m, s), year(y), month(M), day(d)
{
cout << "This is the CalendarClock's constructor" << endl;
}
CalendarClock(const CalendarClock &other) : Clock(other), year(other.year), month(other.month), day(other.day)
{
cout << "This is the CalendarClock's copy constructor" << endl;
}
void show()
{
cout << year << "-" << month << "-" << day << " ";
Clock::showTime();
}
void setTime(int y, int M, int d, int h, int m, int s)
{
Clock::setTime(h, m, s);
year = y;
month = M;
day = d;
}
~CalendarClock()
{
cout << "This is the CalendarClock's destructor" << endl;
}
private:
int year;
int month;
int day;
};
int main(void)
{
CalendarClock c(2020,10,5,9,57,5);
c.show();
Clock *p = &c;
p->showTime();
system("pause");
return 0;
}
虚基类
为了解决多继承时的命名冲突和冗余数据问题,C++ 提出了虚继承,使得在派生类中只保留一份间接基类的成员。
在继承方式前面加上 virtual 关键字就是虚继承。如果遇见sizeof,一个 virtual +4 ,然后去掉重复的部分。
构造函数执行的流程为:
1、传参
2、执行直接或者间接虚基类构造
3、执行直接基类构造
4、为数据成员开辟空间
5、执行构造函数函数体
下面是一道考题:
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i) { cout << i; }
~Base() { }
};
class Base1: virtual public Base
{
public:
Base1(int i, int j = 0) : Base(j) { cout << i; }
~Base1() {}
};
class Base2: virtual public Base
{
public:
Base2(int i, int j = 0) : Base(j) { cout << i; }
~Base2() {}
};
class Derived : public Base2, public Base1
{
public:
Derived(int a, int b, int c, int d) : Base(a), Base2(d), Base1(c), mem2(b), mem1(a) { cout << b; }
private:
Base2 mem2;
Base1 mem1;
};
int main(void)
{
Derived objD (1, 2, 3, 4);
}
仔细思考一下,先初始化虚基类,输出1;
然后按“public Base2, public Base1”的顺序,先初始化Base2,再初始化Base1,输出43;
再初始化mem2,输出02;接着初始化mem1,输出01;最后执行{}里的语句,输出2。