1.继承派生类的定义格式为:
class <派生类名> : <继承方式1> <基类名1>,<继承方式2> <基类名2>,…
{
<派生类新增加的数据成员>
<派生类新增加的成员函数>
};
例子:
class Student {
public:
void display() {
cout << "num: " << num
<< ", name: " << name
<< ", sex: " << sex << endl;
}
protected:
int num;
char name[10];
char sex;
};
class DerivedStudent
: public Student {
public:
void display() { //新增加的成员函数
cout << "age: " << age
<< “, address: " << addr << endl;
}
private:
int age; //新增加的数据成员
string addr; //新增加的数据成员
};
2.注意!!!
在声明派生类时,一般还应当自己定义派生类的构造函数和析构函数,因为构造函数和析构函数是不能从基类继承的。
派生类构造函数功能应该包含对从基类继承过来的继承成员的初始化;派生类析构函数功能应包含从基类继承过来的继承成员的撤消。
3.派生类的构造函数
class Base {
private:
int b_number;
public:
Base() {}
Base(int i) : b_number(i) { }
};
class Derived : public Base {
private:
int d_number;
public:
Derived(int i, int j) : Base(i), d_number(j) { };
};
4.继承构造函数 (using)
class Shape {
public:
Shape(int w, int h) : width(w), height(h) {}
protected:
int width;
int height;
};
// 派生类
class Rectangle : public Shape {
public:
using Shape::Shape;
int getArea() {
return (width * height);
}
};
int main() {
Rectangle Rect(5, 7);
// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
派生类构造函数总结
5.若基类构造函数不带参数:定义派生类构造函数时,可以不必显式的调用基类构造函数
6.基类构造函数带参数:定义派生类构造函数时必须在初始化列表中显式调用基类构造函数,并用在派生类构造函数的形参部分为基类构造函数提供实参。
派生类的析构函数
(由于析构函数都不带参数,故不必显式指明如何调用基类的析构函数)
派生类析构函数的执行顺序与派生类构造函数的调用顺序正好相反:
派生类析构函数
子对象数据成员类的析构函数(如果有子对象数据成员的话)
基类的析构函数
1.派生类和基类
派生类中的成员函数可以访问派生类的所有成员,也能访问其基类的公有成员和受保护成员
派生类的对象能访问派生类的公有数据成员和调用派生类的公有成员函数,公有继承的派生类对象还能够访问其基类的公有成员
2.被调用的成员函数从基类继承而来,但在派生类中被重新定义,此时,如果派生类中与调用函数同名的成员函数参数匹配,则该成员函数被调用,否则返回出错信息。编译程序不会再在基类中查找参数匹配的成员函数
多重继承与虚基类
1.虚继承(菱形继承)
class CPerson {
protected:
string name;
int age;
public:
CPerson() {}
CPerson(string _name, int _age) :name(_name), age(_age) {
cout << "CPerson Ctor!" << endl;
}
~CPerson() {
cout << "CPerson Dtor!" << endl;
}
};
class CStudent : virtual public CPerson {
protected:
int no; //学号
public:
CStudent(string _name, int _age, int _no) :CPerson(_name, _age) {
no = _no;
cout << "CStudent Ctor 1!" << endl;
}
CStudent(int _no) { //调用基类CPerson的默认构造函数
no = _no;
cout << "CStudent Ctor 2!" << endl;
}
~CStudent() {
cout << "CStudent Dtor!" << endl;
}
};
class CTeacher : virtual public CPerson {
protected:
string title; //职称
public:
CTeacher(string _name, int _age, string
_title) :CPerson(_name, _age) {
title = _title;
cout << "CTeacher Ctor 1!" << endl;
}
CTeacher(string _title) { //调用基类CPerson的默认构造函数
title = _title;
cout << "CTeacher Ctor 2!" << endl;
}
~CTeacher() {
cout << "CTeacher Dtor!" << endl;
}
};
class CStudentOnJob : public CStudent, public CTeacher {
private:
string research; //研究方向
public:
CStudentOnJob(string _name, int _age, int _no, string _title, string
_r) :CPerson(_name, _age), CStudent(_no), CTeacher(_title) {
research = _r;
cout << "CStudentOnJob Ctor!" << endl;
}
void print() {
cout << name << " " << age << " " << no << " " << title << " " << research << endl;
}
~CStudentOnJob() {
cout << "CStudentOnJob Dtor!" << endl;
}
};
int main() {
CStudentOnJob s("liming", 26, 0001, "lecturer", "computer");
s.print();
}