public、private、protected继承

1.各类的private成员特性

       publicprivateprotected继承只是影响到基类的public成员和protected成员。对于基类的private只有基类的成员可以访问。就算是限制最松的public继承,在派生类中的成员也不能访问基类的private成员,只能通过调用基类的非private接口来访问。所以基类的private成员和派生类的private成员在派生类中还是有区别的。如下:

class Base
{
public:
	Base(int a):_a(a){}
	void set_a(int a){_a=a;}
private:
	int _a;
};
class Derived:public Base
{
public:
	Derived(int a,int b):Base(a),_b(b){}
	void derived_set_a(int a)
	{_a=a;}
private:
	int _b;
};


编译结果:: error C2248: '_a' : cannot access private member declared in class 'Base'

2.访问级别的改变规则

       再次强调publicprivateprotected继承只是影响到基类的public成员和protected成员。

①如果是public继承,基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员。

②如果是pprotected继承,基类的public成员和protected成员在派生类中为protected成员。

③如果是private继承,基类的public成员和protected成员在派生类中为private成员。

       注意这里private继承的时候,private的成员是可以访问基类中publicprotected成员的。但是是在定义的接口中访问,不是对象直接访问。

class Base
{
public:
	Base(int a):_a(a),protected_a(a){}
	void set_a(int a){_a=a;}
protected:
	int protected_a;
private:
	int _a;
};
class Derived:private Base
{
public:
	Derived(int a,int b):Base(a),_b(b){}
	void print_protected_a(){cout << protected_a;}
private:
	int _b;
};


这段程序是正确的!

       那么protected继承和private继承的区别在哪里?关键在于派生类的派生类的访问权限不一样。如下面两段程序:

class CSample1 {
protected:
    void printProtected() {}
public:
void printPublic() {}
};
class CSample2 : protected CSample1 {};
class CSample3 : public CSample2 {
   void print3() {
      printProtected();
      printPublic();
}
};

class CSample1 {
protected:
  void printProtected() {}
public:
  void printPublic() {}
};
class CSample2 : private CSample1 {};
class CSample3 : public CSample2 {
  void print3() {
    printProtected(); // 编译错误,不可以调用该函数
    printPublic();   // 编译错误,不可以调用该函数
  }
};


3. using声明

       如果进行privateprotected继承,则基类成员的访问级别在派生类中比在基类中更受限:

class Base{
public:
    std::size_t size() const {return n;}

protected:
    std::size_t n;
}
class Derived : private Base{...};


在这一继承层次中,sizeBase中为public,但在Derived中为private。为了使sizeDerived中成为public,可以在Derivedpublic部分增加一个using声明。如下这样改变Derived的定义,可以使size成员能够被用户访问,并使n能够被从Derived派生的类访问:

class Derived : private Base{
public:
    using Base::size;
privated:
    using Base::n;
}


4.struct与class的区别

       structclass保留字定义的类具有不同的默认访问级别。同样,默认继承访问级别根据使用哪个保留字定义派生类也不相同。使用class保留字定义的派生类默认具有private继承,而用struct保留字定义的类默认具有public继承:

class Base{/*...*/}
struct D1 : Base{/*...*/};  //public  inheritance by default
class  D2 : Base{/*...*/};  //private inheritance by default


       有一种常见的误解认为用struct保留字定义的类与用class定义的类有更大的区别。实际上它们唯一的不同只是①默认的成员保护级别和②默认的派生保护级别,除此之外,再也没有其他的区别。

5.例题

       下面程序标记为A至J的语句哪些是正确的哪些是错误的?

#include <iostream>
using namespace std;
class Parent
{
public:
	Parent(int var = -1)
	{
		m_nPub = var;
		m_nPtd = var;
		m_nPrt = var;
	}
public:
	int m_nPub;
protected:
	int m_nPtd;
private:
	int m_nPrt;
};

class Child1:public Parent
{
public:
	int GetPub(){return m_nPub;}
	int GetPtd(){return m_nPtd;}
	int GetPrt(){return m_nPrt;} //A
};

class Child2:protected Parent
{
public:
	int GetPub(){return m_nPub;}
	int GetPtd(){return m_nPtd;}
	int GetPrt(){return m_nPrt;} //B
};

class Child3:private Parent
{
public:
	int GetPub(){return m_nPub;}
	int GetPtd(){return m_nPtd;}
	int GetPrt(){return m_nPrt;} //C
};

int main()
{
	Child1 cd1;
	Child2 cd2;
	Child3 cd3;

	int nVal=0;
	//public 继承
	cd1.m_nPub=nVal;//D
	cd1.m_nPtd=nVal;//E
	nVal=cd1.GetPtd();//F
	//protected 继承
	cd2.m_nPub=nVal;//G
	nVal=cd2.GetPtd();//H
	//private 继承
	cd3.m_nPub=nVal;//I
	nVal=cd3.GetPtd();//J

	return 0;
}
       正确的是:DFHJ;错误的是:ABCEGI



 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值