C++ 继承、友元、权限
2016-02-27 18:34
459 查看
1,C++类的继承分 public、protected、private三种:
基类的成员: public protected private
被public继承后: public protected
private
被protected继承后:
protected protected
private
被private继承后:
private private
private
注意,在子类定义中可以通过 using Base::MemberNameOrFuncName; 来重新定义权限
2,对于友元类,不具有继承性,例如:A是B的友元类,但A的基类及子类默认情况下不是B的友元类。
3,1) 基类的友元函数或友元类可以访问基类的所有成员
2) 基类的友元函数或友元类可以访问public继承的子类中的父类所有成员
3)
基类的友元函数或友元类不可以访问非public继承的子类中的父类所有成员
4) 基类的友元函数或友元类不可以访问子类中非父类的非public成员
5)子类的友元函数或友元类可以访问子类的所有成员
6) 子类的友元函数或友元类可以访问任意继承的子类中的父类所有成员
7) 子类的友元函数或友元类不可以直接访问父类对象的非public成员
简单记忆如下:
父亲的朋友可以直接找父亲,可以找公开住在儿子家中的父亲,但不能找偷偷(protected/private)住在儿子家中的父亲,更不能直接找儿子。
儿子的朋友可以直接找儿子,儿子的朋友可以找任何方式住在儿子家中的父亲,但不能直接去父亲家找父亲。
另外记住,成员函数的权限与友元是完全一样的,即上述内容同样适用于成员函数,包括拷贝构造函数与赋值构造函数。
比如用户代码执行base = derive这种代码,执行的是base的赋值构造函数,如果是非public继承且base里有非public成员变量,则编译不通过(public继承可以)。derive=base更是不允许的(这种编译器不会默认定义赋值方式),只能是derive=derive这种。
但如果在子类的成员函数或友元内,因为处于子类作用域,不论何种继承,base = derive是可以的。
基类的成员: public protected private
被public继承后: public protected
private
被protected继承后:
protected protected
private
被private继承后:
private private
private
注意,在子类定义中可以通过 using Base::MemberNameOrFuncName; 来重新定义权限
2,对于友元类,不具有继承性,例如:A是B的友元类,但A的基类及子类默认情况下不是B的友元类。
3,1) 基类的友元函数或友元类可以访问基类的所有成员
2) 基类的友元函数或友元类可以访问public继承的子类中的父类所有成员
3)
基类的友元函数或友元类不可以访问非public继承的子类中的父类所有成员
4) 基类的友元函数或友元类不可以访问子类中非父类的非public成员
5)子类的友元函数或友元类可以访问子类的所有成员
6) 子类的友元函数或友元类可以访问任意继承的子类中的父类所有成员
7) 子类的友元函数或友元类不可以直接访问父类对象的非public成员
简单记忆如下:
父亲的朋友可以直接找父亲,可以找公开住在儿子家中的父亲,但不能找偷偷(protected/private)住在儿子家中的父亲,更不能直接找儿子。
儿子的朋友可以直接找儿子,儿子的朋友可以找任何方式住在儿子家中的父亲,但不能直接去父亲家找父亲。
另外记住,成员函数的权限与友元是完全一样的,即上述内容同样适用于成员函数,包括拷贝构造函数与赋值构造函数。
比如用户代码执行base = derive这种代码,执行的是base的赋值构造函数,如果是非public继承且base里有非public成员变量,则编译不通过(public继承可以)。derive=base更是不允许的(这种编译器不会默认定义赋值方式),只能是derive=derive这种。
但如果在子类的成员函数或友元内,因为处于子类作用域,不论何种继承,base = derive是可以的。
//ClassTest.h #pragma once class Base; class Base; class Derive11; class Derive12; int BaseFriend(Derive11& derive1,Base& base, Derive12& devive2); int Derive11Friend(Derive11& derive1,Base& base, Derive12& devive2); int Derive12Friend(Derive11& derive1,Base& base, Derive12& derive2); int Derive13Friend(); class Base { public: //注:假如这里写private或不写,则Base及其子类均无法在外部定义对象 Base(){} virtual ~Base(){} friend int BaseFriend(Derive11& derive1,Base& base, Derive12& devive2); protected: int m_nBasePro; private: int m_nBasePri; }; class Derive11 :public Base { public: Derive11(void); virtual ~Derive11(void); friend int Derive11Friend(Derive11& derive1,Base& base, Derive12& devive2); public: void Test(); Derive11& operator = (const Derive11& bb){ m_nBasePro = bb.m_nBasePro;return *this;} protected: void FuncProtected(); int m_nProtected; private: void FuncPrivate(); int m_nPrivate; }; class Derive12 :protected Base { public: Derive12(void){}; virtual ~Derive12(void){}; friend int Derive12Friend(Derive11& derive1,Base& base, Derive12& devive2); protected: void FuncProtected(){}; int m_nProtected; private: void FuncPrivate(){}; int m_nPrivate; }; class Derive13 :private Base { public: Derive13(void){}; virtual ~Derive13(void){}; protected: void FuncProtected(){}; int m_nProtected; private: void FuncPrivate(){}; int m_nPrivate; }; //ClassTest.cpp #include "ClassTest.h" Derive11::Derive11(void) { } Derive11::~Derive11(void) { } void Derive11::FuncProtected() { } void Derive11::FuncPrivate() { } void Derive11::Test() { } int BaseFriend(Derive11& derive1,Base& base, Derive12& derive2) { base.m_nBasePri = base.m_nBasePro = 0; //derive1.FuncProtected(); //父亲的朋友不能直接找儿子 //derive1.m_nProtected = 0; //父亲的朋友不能直接找儿子 derive1.m_nBasePro = 0;//父亲的朋友可以访问公开住在儿子家中的父亲 //derive2.m_nBasePro = 0;//父亲的朋友不可以访问偷偷住在儿子家中的父亲 //derive1 = base; //不行,与儿子 4000 的朋友不能直接访问父亲一样,可以访问同一子类的 base = derive1; //行,赋值构造与友元的权限一样 Base bb(derive1); //行,赋值构造与友元的权限一样 //Base cc(derive2); //不行,拷贝构造与友元的权限一样,此处相当于外部调用,无特权 //base = derive2; //不行,赋值构造与友元的权限一样,此处相当于外部调用,无特权 return 0; } int Derive11Friend(Derive11& derive1,Base& base, Derive12& derive2) { //base.m_nBasePri = base.m_nBasePro = 0; //孩子的朋友不能直接找父亲 derive1.m_nBasePro = 0;//儿子的朋友可以访问任何方式住在儿子家中的父亲 //derive2.m_nBasePro = 0;//大儿子的朋友不可以访问住在二儿子家中的父亲(不论是否公开) return 1; } int Derive12Friend(Derive11& derive1,Base& base, Derive12& derive2) { Base cc(derive2); //可以,友元里和成员函数里就可以访问,有特权 base = derive2; //可以 return 2; } int Derive13Friend() { return 3; }
相关文章推荐
- C语言中的类型转换
- C语言创建并使用lib
- c语言编写通讯录
- C++学习笔记49——继承中的复制构造函数与赋值操作符
- 图的深度优先搜索/Depth-first search/C++
- C++ 多态详解
- C语言:未包含头文件引起的奇怪错误
- C++中的ostringstream、istringstream和getline()
- 在VS2015中用C++创建MFC规则动态库DLL
- opencl:C++接口配置抛出异常
- C++多态
- C++暂时对象
- opencl:C++实现双线性插值图像缩放
- 九度-题目1054:字符串内排序
- 有意思的 猎豹移动c++面试题
- C语言 指向结构体数组的指针
- C语言 指向结构体变量的指针
- opencl: C++ 接口(cl.hpp)创建kernel
- C++ Primer 学习笔记——顺序容器的string操作
- 1071. Speech Patterns (25)