您的位置:首页 > 编程语言 > C语言/C++

C++基础-继承

2017-07-18 20:43 369 查看

继承

原则:is -a

父类/子类

基类/派生类

语法

class 派生类:[访问限定符] 基类{
成员
};


如果不写继承访问限定符,默认是‘private’。

实例:图形继承

成员的访问权限

/‘public’‘protected’‘private’
类成员函数
友元函数
子类函数×
类对象××
子类继承类父类所有的成员变量和成员函数。与访问限定 符无关。访问限定符只是限制了访问。

子类访问父类成员变量,把父类成员变量访问限制符,改为‘protected’。

继承访问权限变化

分为子类内部和子类对象两种访问方式。

子类内部访问‘public’继承的父类成员变量

class Base{
public:
int public_data;
protected:
int protected_data;
private:
int private_data;
};
class Derive:public Base{
public:
void test(){
cout<< public_data<<endl;
cout<< protected_data<<endl;
cout<<private_data<<endl;
}
};


子类内部访问‘public’继承的父类成员函数

#include <iostream>

using std::cout;
using std::endl;
class Base{
public:
void public_func(){};
protected:
void protected_func(){};
private:
void private_func(){};
};
class Derive:public Base{
public:
void test(){
public_func();
protected_func();
private_func();
}
};


子类内部访问父类成员

‘public’‘protected’‘private’
public 继承
protected 继承
private 继承
子类内部访问父类成员,只能访问‘public’和‘protected’成员。

子类对象访问父类成员

‘public’‘protected’‘private’
public 继承×
protected 继承××
private××
子类只有‘public’继承父类的时候,才能访问父类的‘public’成员,其他都不能访问。

通常子类使用‘public’继承父类。

子类对象访问父类成员访问限定符的变化

|’public’‘protected’‘private’
public 继承‘public’‘protected’
protected 继承‘protected’‘protected’
private 继承‘private’‘private’
* 派生类的构造函数与析构函数的调用顺序

* 派生类的构造函数调用顺序:子对象构造、成员变量构造、父对象构造的顺序

* 派生类的析构函数调用顺序:子对象析构、成员变量析构、父对象析构的顺序

#include <iostream>
using std::cout;
using std::endl;
class Member{
public:
Member(){
cout << "Member Init" <<endl;
}
~Member(){
cout << "Member Destroy" <<endl;
}
};
class Parent{
public:
Parent(){
cout << "Parent Init" << endl;
}
~Parent(){
cout << "Parent Destory" << endl;
}
};
class Son:public Parent{
public:
Son(){
cout << "Son Init" << endl;
}
~Son(){
cout << "Son Destory" <<endl;
}
private:
Member m;
};
int main(){
Son son;
}


没有默认构造函数的基数在派生类的初始化,必须在初始化列表中初始化

同名隐藏规则

概念:子类的成员函数与基类成员函数同名,子类的函数将会隐藏基类的所有同名函数。

#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
void show(int data){
cout<<"Base::show("<<data<<")"<<endl;
};
class Derive:public Base{
public:
void show(){
cout<<"Derive::show()"<<endl;
}
};
int main(){
Derive derive;
derive.show();
derive.Base::show(123);
}


解决方法:

‘Derived’类中的名称会隐藏 ‘Base’类中同名的名称,在’public’继承中我们可以通过引入’using’声明。

函数同名的情况总结

名称英语
重载overload
重写(覆盖)override
隐藏hide
* 赋值兼容规则:在任何需要基类对象的地方都可以使用公有的派生类对象来代替。反之,不可。

向上转换:派生类对象赋值给基类

向下转换:基类对象赋值给派生类

派生类对象可以赋值给基类的对象

int main(){
Derive derive;
Base& base = derive;
base.show(123);

}


引用访问派生类中由基类继承来的对象,不能访问派生类中的新成员

多重继承:一个类可以同时继承多个父类的行为和特征功能。

class 类名:[访问限定符]基类1,[访问限定符] 基类2{
};


多重继承基类构造顺序:??

钻石继承/菱形继承

概念:两个子类继承同一个父类,而又有子类同时继承这两个子类。

问题:不同途径继承来的同名的成员在内存中有不同的拷贝,造成数据不一致。

解决:虚继承&虚基类

虚继承:在继承定义中包含了‘virtual’关键字的继承关系。

虚基类:在虚继承体系中的通过‘virtual’继承而来的基类。

class 类名:publc virtual 基类{
};


虚基类是一个相对概念,在虚继承关系中,父类相对于子类是虚基类

虚基类与普通基类的构造顺序:先构造虚基类,然后构造普通基类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: