共计 3411 个字符,预计需要花费 9 分钟才能阅读完成。
引言
前段时间买了一本C++之父编写的英文版C++11书籍,想复习C++基础,最近看到了类继承这一章节。因此顺便总结一下。在C++中,类是提供封装的逻辑单位,类的每一个对象都包含有描述其自身状态的数据集合,并且通过接收特定的消息来处理这个数据集合。如果程序设计人员能够通过增加、修改或替换指定类的部分内容的方法对该类进行剪裁,就可以适应不同的应用,从而在很大程度上增强了数据封装的价值,而接下来要讨论的继承就完全可以实现这种操作。
继承分为单继承、多重继承、虚继承(ps:当然虚继承也可以划分到到其他两个当中),今天主要讲的是单继承,从基础理解继承过程中的基类、继承之类访问的权限控制。
继承的方式
- Public公有继承:对于公有继承而言,基类中的成员在继承子类中保留了原来的权限,也就是基类中的Public在子类中的访问权限仍然是Public,同理对于Protected成员也是这样。重点是我们需要注意的是子类没有直接访问基类Private成员的权限,如果需要访问基类中的私有成员需要通过基类中的公有成员接口,否则是无法访问私有成员的。
- Protected保护继承:对于保护继承而言,其中基类中的Public和Protected成员的权限在子类中各降一级,也就是原来的Public->Protected,Protected->Private。重点又来了,其私有成员的访问权限控制和在公有继承中描述的一致。
- Private私有继承:对于私有继承而言,其中基类中的Public和Protected成员的权限在子类中都变为了Private属性。与此同时对于基类中的私有成员在继承子类中的情况与公有继承一致。
注意:
- 不同的继承方式影响着基类成员函数在继承子类中的权限控制。对于继承子类的对象和继承子类成员函数的权限都是有着很大的影响,大家一定要注意子类对象的访问权限与子类成员函数的访问权限是完全不一样的概念。
- 在三种继承方式中都存在一个共同的特点就是基类中的私有成员在继承子类中的表现形式是一致的。
下面代码表示三种继承方式权限的控制:
(1)公有继承
class base{
public:
void showpublic();
protected:
void showptoteced();
private:
void showprivate();
};
class derived:public base
{
public:
derived();
~ derived();
void show(){
}
//只是为了显示继承的权限显示效果
//在实际代码中可不能这么写,编译都过不了
public:
void showpublic();
protected:
void showptoteced();
NO ACCESS TO private;
};
(2)保护继承
class base{
public:
void showpublic();
protected:
void showptoteced();
private:
void showprivate();
};
class derived:public base
{
public:
derived();
~ derived();
void show(){
}
//只是为了显示继承的权限显示效果
//在实际代码中可不能这么写,编译都过不了
protected:
void showpublic();
private:
void showptoteced();
NO ACCESS TO private;
};
(3)私有继承
class base{
public:
void showpublic();
protected:
void showptoteced();
private:
void showprivate();
};
class derived:public base
{
public:
derived();
~ derived();
void show(){
}
//只是为了显示继承的权限显示效果
//在实际代码中可不能这么写,编译都过不了
private:
void showpublic();
private:
void showptoteced();
NO ACCESS TO private;
};
下面以实验代码来解释继承过程中权限的控制:
#include <iostream>
using namespace std;
class base{
public:
void showpublic(){ cout << "正在调用父类公有权限函数" << endl; };
protected:
void showptoteced(){ cout << "正在调用父类保护权限函数" << endl; };
private:
void showprivate(){ cout << "正在调用父类私有权限函数" << endl; };
};
class publicderived :public base
{
public:
void show(){
//showpublic和showptoteced分别保持着Public和Protected访问权限
showpublic();
showptoteced();
//无法调用showprivate()
//showprivate();
}
};
class protectedderived :protected base
{
public:
void show(){
//showpublic和showptoteced分别保持着Protected和private访问权限
showpublic();
showptoteced();
//无法调用showprivate()
//showprivate();
}
};
class privatederived :private base
{
public:
void show(){
//showpublic和showptoteced分别保持着private和private访问权限
showpublic();
showptoteced();
//无法调用showprivate()
//showprivate();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//公有继承实例
cout << "公有继承测试------>" << endl;
publicderived test;
//注意之前描述访问权限时提到的继承子类的权限与继承子类成员函数的权限
//子类对象可以访问自己的公有成员函数show();
test.show();
//showpublic()由于是从base中public继承过来的,子类对象拥有访问权限
//但是此时你无法使用test.showptoteced(),会提示你没有访问权限,showprivate()也是这样
//虽然继承子类对象没有访问权限,但是子类的成员函数show()是具有权限的。
test.showpublic();
//--------------------------------------------------------------------------------
//保护继承实例
cout << "保护继承测试------>" << endl;
protectedderived test1;
test1.show();
//此时保护继承的权限在之前描述时public和protected都各降一级了,因此通过对象无法直接调用
//--------------------------------------------------------------------------------
//私有继承实例
cout << "私有继承测试------>" << endl;
privatederived test2;
test2.show();
return 0;
}
结论:
在上面例子中可以看到在单继承过程中的权限控制解析。然而在继承过程中存在子类与父类中函数一致的情况出现和继承子类隐式向上变换等多种问题,下面给出部分结论,再介绍虚函数的时候还会介绍。
- 如果以一个基类指针指向派生类对象,那么经由该指针只能调用基类所定义的函数
- 如果你以一个派生类的指针指向一个基类对象,你必须先做明显的强制转换,但是这样做很危险
- 如果基类和派生类都定义了相同名的成员函数,那么通过对象指针调用成员函数时候,调用的函数是由指针的原始类型而定,而不是看指针指向的对象的类型而定
正文完
请博主喝杯咖啡吧!