C++笔记: 继承,友元
2010-04-08 14:43
141 查看
//---(一)友元关系----------
友元关系不可继承,Base是基类,Derive是派生类,F是Base的友元, 这么说来, "F不能访问Derive的private成员"是无误的;
但是还是不够准确,假设Base有一个privata的virtual函数func(),Derive继承并重写了此函数,那么在基类的友元F中有如下代码:
看似F通过Base*指针绕过了检查, 并由虚函数表找到了Derive::func(), 是不是想到了"友元破坏封装"这句话?
与其把友元看作"破坏封装"的罪魁祸首, 不如把这种机制称为"基类的对外接口", 只要基类提供了这样一个接口:通过此接口我们可以间接访问基类的私有成员, 这个"接口"可以是一个public函数,也可以是一种"友元关系", 正是通过这个"友元关系"接口, 派生类中的私有成员可以被间接访问了;
//---(二)private继承----------
以上方式3中的P4指针仍可正常访问virtual table内的函数;
友元关系不可继承,Base是基类,Derive是派生类,F是Base的友元, 这么说来, "F不能访问Derive的private成员"是无误的;
但是还是不够准确,假设Base有一个privata的virtual函数func(),Derive继承并重写了此函数,那么在基类的友元F中有如下代码:
Derive* p1=new Derive(); p1->func();//这句肯定报错 Base* p2=new Derive(); p2->func();//这句不报错,且会执行Derive::func()
看似F通过Base*指针绕过了检查, 并由虚函数表找到了Derive::func(), 是不是想到了"友元破坏封装"这句话?
与其把友元看作"破坏封装"的罪魁祸首, 不如把这种机制称为"基类的对外接口", 只要基类提供了这样一个接口:通过此接口我们可以间接访问基类的私有成员, 这个"接口"可以是一个public函数,也可以是一种"友元关系", 正是通过这个"友元关系"接口, 派生类中的私有成员可以被间接访问了;
//---(二)private继承----------
class Base { public: char mchar; Base(){mchar='B';} }; class Derive :private Base { public: Derive(){mchar='D';} }; //用户访问Derive::mchar方式1 Derive* p1=new Derive(); printf("%c",p1->mchar);//此处报错,无法访问private成员 //用户访问Derive::mchar方式2 Base* p2=new Derive();//此处报错,无法隐式转换private的派生类 printf("%c",p2->mchar); //用户访问Derive::mchar方式3 Derive* p3=new Derive(); Base* p4=(Base*)p3; //仅警告 printf("%c",p3->mchar);//可以访问Derive::mchar,打印'D'
以上方式3中的P4指针仍可正常访问virtual table内的函数;
相关文章推荐
- C++学习笔记46——友元与继承
- 友元关系与继承——《C++ primer》笔记,书中的小bug
- C++笔记: 继承,友元
- j2se学习笔记-继承&构造方法
- JavaScript继承(图解笔记)
- 学习Swift笔记 (十五)Swift继承的用法
- Java学习笔记---继承和super的用法
- Java学习笔记:继承与多态
- java学习笔记3_继承与多态
- Java笔记整理——接口、继承与多态
- JAVA学习笔记(一)---单例模式与继承
- Django笔记 Model的继承和操作
- Java学习笔记11 面向对象之继承与…
- C++笔记记录Ⅲ 继承与多态
- Swift学习笔记(十一)继承
- C#类与继承 笔记
- Effective C++笔记: 继承和面向对象设计(一)
- C++学习笔记:继承
- Entity Framework with MySQL 学习笔记一(继承)
- Lua学习笔记5:类及继承的实现