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

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是可以的。

//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;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: