C++的访问控制符与多态之间的关系
2016-01-20 21:40
501 查看
本文将着重讨论C++的访问控制符(private、protected、public)与多态行为之间的关系。
访问控制符主要用于限制类成员的访问权限和限制类与类之间的继承关系(私有继承、保护继承、公有继承),按访问级别的不同,我们来对访问控制符从大到小排个序:
public>protected>private
多态行为的产生也需要有几个条件:
1)基类有虚函数或纯虚函数
2)存在继承,并且派生类override(覆盖)了基类了虚函数或纯虚函数
3)通过基类的指针或引用调用虚函数
这三者缺一不可,貌似多态和访问控制符没有什么关系,那么到底有没有关系呢?
接下来我们分几种情况来讨论这个问题:
1、公有继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限不发生变化:基类的公有数据成员在派生类中的访问权限还是公有的;基类的保护数据成员在派生类中的访问权限还是保护的;基类的私有数据成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
//编译、运行,上面的代码能输出:print1,I'm sub1!//通过基类指针调用</span>
print1,I'm sub1!//通过sub1实例调用
print2,I'm sub1!
print3,I'm sub1!
priint1, I'm sub2! //通过基类指针调用
print1,I'm sub3!//通过基类指针调用
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限均未发生变化;
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为
2、保护继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限均为保护的,即:基类的公有数据成员在派生类中的访问权限是保护的;基类的保护数据成员在派生类中的访问权限是保护的;基类的私有成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
//编译运行上面的代码,一样能产生多态行为并且与上面的输出结果一致;
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限发生了变化:public->protected,protected和private未发生变化
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为;
3、私有继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限均为私有的,即:基类的公有数据成员在派生类中的访问权限是私有的;基类的保护数据成员在派生类中的访问权限是私有的;基类的私有成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
//编译运行上面的代码,一样能产生多态行为并且与上面的输出结果一致;
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限均变成了private;
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为;
结论:
1、继承方式(private、protected、public)影响数据成员的访问权限
2、继承方式(private、protected、public)不会影响多态行为的发生
3、在派生类中修改函数成员的访问控制符也不会影响多态行为的发生
访问控制符主要用于限制类成员的访问权限和限制类与类之间的继承关系(私有继承、保护继承、公有继承),按访问级别的不同,我们来对访问控制符从大到小排个序:
public>protected>private
多态行为的产生也需要有几个条件:
1)基类有虚函数或纯虚函数
2)存在继承,并且派生类override(覆盖)了基类了虚函数或纯虚函数
3)通过基类的指针或引用调用虚函数
这三者缺一不可,貌似多态和访问控制符没有什么关系,那么到底有没有关系呢?
接下来我们分几种情况来讨论这个问题:
1、公有继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限不发生变化:基类的公有数据成员在派生类中的访问权限还是公有的;基类的保护数据成员在派生类中的访问权限还是保护的;基类的私有数据成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
#include <iostream> using namespace std; class Base { public: Base():ID1(0),ID2(0),ID3(0){} virtual ~Base(){} int ID1; virtual void print1()=0; protected: int ID2; virtual void print2()=0; private: int ID3; virtual void print3()=0; }; class Sub1:public Base { public: Sub1(){} virtual ~Sub1(){} virtual void print1() { cout<<"print1,I'm sub1!"<<endl; } virtual void print2() { cout<<"print2,I'm sub1!"<<endl; } virtual void print3() { cout<<"print3,I'm sub1!"<<endl; } }; class Sub2:public Base { public: Sub2(){} virtual ~Sub2(){} protected: virtual void print1() { cout<<"print1,I'm sub2!"<<endl; } virtual void print2() { cout<<"print2,I'm sub2!"<<endl; } virtual void print3() { cout<<"print3,I'm sub2!"<<endl; } }; class Sub3:private Base { public: Sub3(){} virtual ~Sub3(){} private: virtual void print1() { cout<<"print1,I'm sub3!"<<endl; } virtual void print2() { cout<<"print2,I'm sub3!"<<endl; } virtual void print3() { cout<<"print3,I'm sub3!"<<endl; } }; int main(int argc,char *argv[]) { Sub1 sub1; Sub2 sub2; Sub3 sub3; Base *pb=(Base*)&sub1; pb->print1(); sub1.print1(); sub1.print2(); sub1.print3(); cout<<endl; pb=(Base*)&sub2; pb->print1(); cout<<endl; pb=(Base*)&sub3; pb->print1(); cout<<endl; return 0; }
//编译、运行,上面的代码能输出:print1,I'm sub1!//通过基类指针调用</span>
print1,I'm sub1!//通过sub1实例调用
print2,I'm sub1!
print3,I'm sub1!
priint1, I'm sub2! //通过基类指针调用
print1,I'm sub3!//通过基类指针调用
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限均未发生变化;
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为
2、保护继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限均为保护的,即:基类的公有数据成员在派生类中的访问权限是保护的;基类的保护数据成员在派生类中的访问权限是保护的;基类的私有成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
#include <iostream> using namespace std; class Base { public: Base():ID1(0),ID2(0),ID3(0){} virtual ~Base(){} int ID1; virtual void print1()=0; protected: int ID2; virtual void print2()=0; private: int ID3; virtual void print3()=0; }; class Sub1:protected Base { public: Sub1(){} virtual ~Sub1(){} virtual void print1() { cout<<"print1,I'm sub1!"<<endl; } virtual void print2() { cout<<"print2,I'm sub1!"<<endl; } virtual void print3() { cout<<"print3,I'm sub1!"<<endl; } }; class Sub2:protected Base { public: Sub2(){} virtual ~Sub2(){} protected: virtual void print1() { cout<<"print1,I'm sub2!"<<endl; } virtual void print2() { cout<<"print2,I'm sub2!"<<endl; } virtual void print3() { cout<<"print3,I'm sub2!"<<endl; } }; class Sub3:protected Base { public: Sub3(){} virtual ~Sub3(){} private: virtual void print1() { cout<<"print1,I'm sub3!"<<endl; } virtual void print2() { cout<<"print2,I'm sub3!"<<endl; } virtual void print3() { cout<<"print3,I'm sub3!"<<endl; } }; int main(int argc,char *argv[]) { Sub1 sub1; Sub2 sub2; Sub3 sub3; Base *pb=(Base*)&sub1; pb->print1(); sub1.print1(); sub1.print2(); sub1.print3(); cout<<endl; pb=(Base*)&sub2; pb->print1(); cout<<endl; pb=(Base*)&sub3; pb->print1(); cout<<endl; return 0; }
//编译运行上面的代码,一样能产生多态行为并且与上面的输出结果一致;
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限发生了变化:public->protected,protected和private未发生变化
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为;
3、私有继承
特点:在派生类中,基类所有可访问数据成员(public、protected)的默认访问权限均为私有的,即:基类的公有数据成员在派生类中的访问权限是私有的;基类的保护数据成员在派生类中的访问权限是私有的;基类的私有成员在派生类中是不可被访问的;但是函数成员的访问权限可由派生类指定,不论指定为何种访问权限,都不影响多态的发生,详见下面的代码:
#include <iostream> using namespace std; class Base { public: Base():ID1(0),ID2(0),ID3(0){} virtual ~Base(){} int ID1; virtual void print1()=0; protected: int ID2; virtual void print2()=0; private: int ID3; virtual void print3()=0; }; class Sub1:private Base { public: Sub1(){} virtual ~Sub1(){} virtual void print1() { cout<<"print1,I'm sub1!"<<endl; } virtual void print2() { cout<<"print2,I'm sub1!"<<endl; } virtual void print3() { cout<<"print3,I'm sub1!"<<endl; } }; class Sub2:private Base { public: Sub2(){} virtual ~Sub2(){} protected: virtual void print1() { cout<<"print1,I'm sub2!"<<endl; } virtual void print2() { cout<<"print2,I'm sub2!"<<endl; } virtual void print3() { cout<<"print3,I'm sub2!"<<endl; } }; class Sub3:private Base { public: Sub3(){} virtual ~Sub3(){} private: virtual void print1() { cout<<"print1,I'm sub3!"<<endl; } virtual void print2() { cout<<"print2,I'm sub3!"<<endl; } virtual void print3() { cout<<"print3,I'm sub3!"<<endl; } }; int main(int argc,char *argv[]) { Sub1 sub1; Sub2 sub2; Sub3 sub3; Base *pb=(Base*)&sub1; pb->print1(); sub1.print1(); sub1.print2(); sub1.print3(); cout<<endl; pb=(Base*)&sub2; pb->print1(); cout<<endl; pb=(Base*)&sub3; pb->print1(); cout<<endl; return 0; }
//编译运行上面的代码,一样能产生多态行为并且与上面的输出结果一致;
成员访问权限:
1)、不可访问数据成员ID3在派生类中依然不可访问,可访问数据员在派生类中的访问权限均变成了private;
2)、成员函数访问权限在派生类中可以修改为private、protected、public之中的任何一个,并且不影响多态行为;
结论:
1、继承方式(private、protected、public)影响数据成员的访问权限
2、继承方式(private、protected、public)不会影响多态行为的发生
3、在派生类中修改函数成员的访问控制符也不会影响多态行为的发生
相关文章推荐
- C++开发人脸性别识别教程(14)——灰度图像识别BUG处理
- sys/param.h 和 limits.h头文件说明
- c++中new和malloc的区别
- c语言成绩统计系统
- C++迭代器
- C和C++里面常见错误和异常出现怎么解决总结(不断更新)
- C++ 现代编程风格速查表
- 遗传算法与C++实现
- C++11异常处理 noexcept
- C++中重载、重写(覆盖)和隐藏的区别实例分析
- 【C++】 复数类操作
- C语言开发函数库时对外接口隐藏库内结构体实现细节的方法
- C++:模板函数2(多个数的和)
- C/C++中extern关键字详解
- C++:模板函数1(2个数的和)
- C++:重载函数2(计算面积)
- C++中extern关键字
- 在编译VC++6.0是,出现fatal error C1010: unexpected end of file while looking for precompiled header directi
- c++回调函数 callback
- 新手学习C语言时常犯的错误