7_继承与派生
继承与派生
- 吸收基类成员
- 改造基类成员
- 新增派生类成员
class 派生类名:继承方式 基类名
{
成员声明;
}
class Derived: public Base
{
public:
Derived ();
~Derived ();
};
继承方式
公有继承
- 基类的public和protected成员:访问属性在派生类中保持不变
- 基类的private成员:不可直接访问
类型转换
公有派生类对象可以当作基类的对象使用(可以隐含转换),反之不行。
但是转换后,派生类只能使用从基类继承来的成员。
派生类的构造和析构
一般自己写新的构造函数,但c++11:使用using继承基类的构造函数,但是只能初始化从基类继承的成员。
先基类参数初始化,再派生类参数初始化
派生类名::派生类名(基类所需的形参,本类成员所需的形参):
基类名(参数表), 本类成员初始化列表
{
//其他初始化;
};
#include<iostream>
using namespace std;
class B {
public:
B();
B(int i);
~B();
void print() const;
private:
int b;
};
B::B() {
b=0;
cout << "B's default constructor called." << endl;
}
B::B(int i) {
b=i;
cout << "B's constructor called." << endl;
}
B::~B() {
cout << "B's destructor called." << endl;
}
void B::print() const {
cout << b << endl;
}
class C: public B {
public:
C();
C(int i, int j);
~C();
void print() const;
private:
int c;
};
C::C() {
c = 0;
cout << "C's default constructor called." << endl;
}
C::C(int i,int j): B(i), c(j){
cout << "C's constructor called." << endl;
}
复制构造函数
派生类未定义复制构造函数的情况
- 编译器会在需要时生成一个隐含的复制构造函数;
- 先调用基类的复制构造函数;
- 再为派生类新增的成员执行复制。
派生类定义了复制构造函数的情况
- 一般都要为基类的复制构造函数传递参数。
- 复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数。
- 基类的复制构造函数形参类型是基类对象的引用,实参可以是派生类对象的引用
- 例如: C::C(const C &c1): B(c1)
析构函数
先派生类参数析构,再基类参数析构
- 析构函数不被继承,派生类如果需要,要自行声明析构函数。
- 声明方法与无继承关系时类的析构函数相同。
- 不需要显式地调用基类的析构函数,系统会自动隐式调用。
- 先执行派生类析构函数的函数体,再调用基类的析构函数。
派生类成员的访问
一般是同名隐藏规则,但是也可以通过作用域操作符访问
#include <iostream>
using namespace std;
class Base1 {
public:
int var;
void fun() { cout << "Member of Base1" << endl; }
};
class Base2 {
public:
int var;
void fun() { cout << "Member of Base2" << endl; }
};
class Derived: public Base1, public Base2 {
public:
int var;
void fun() { cout << "Member of Derived" << endl; }
};
int main() {
Derived d;
Derived *p = &d;
//访问Derived类成员
d.var = 1;
d.fun();
//访问Base1基类成员
d.Base1::var = 2;
d.Base1::fun();
//访问Base2基类成员
p->Base2::var = 3;
p->Base2::fun();
return 0;
}