C++中 public和private派生類繼承問題和訪問權限問題

本文連接地址:http://hi.baidu.com/laoyang1018/blog/item/933d5243a75c3f1a9313c6db.html 

#######################
php

//聲明: 1  本帖做者是:百變老羊 ,至此感謝!html

              2  紅色背景字體爲我的閱讀重點!c++

#######################
函數

C++中 public和private派生類繼承問題和訪問權限問題

當一個子類從父類繼承時,父類的全部成員成爲子類的成員,此時對父類成員的訪問狀態由繼承時使用的繼承限定符決定。
1.若是子類從父類繼承時使用的繼承限定符是public,那麼


(1)父類的public成員成爲子類的public成員,
容許類之外的代碼訪問這些成員字體

(2)父類的private成員仍舊是父類的private成員,子類成員不能夠訪問這些成員;ui

(3)父類的protected成員成爲子類的protected成員,只容許子類成員訪問;url

2.若是子類從父類繼承時使用的繼承限定符是private,那麼


(1)父類的public成員成爲子類的private成員,
只容許子類成員訪問spa

(2)父類的private成員仍舊是父類的private成員,子類成員不能夠訪問這些成員;


(3)父類的protected成員成爲子類的private成員,只容許子類成員訪問;
.net

3.若是子類從父類繼承時使用的繼承限定符是protected,那麼


(1)父類的public成員成爲子類的protected成員,
只容許子類成員訪問3d

(2)父類的private成員仍舊是父類的private成員,子類成員不能夠訪問這些成員;


(3)父類的public成員成爲子類的protected成員,只容許子類成員訪問;


至於類中不一樣成員(public、private和protected)的訪問狀態就不細說了。

c++訪問權限和派生繼承

在基類中,public表示成員是公有的:能夠由程序中任何函數訪問。因此公有成員通常是成員函數,它提供了外部程序與類的接口功能,用戶經過公有成員訪問該類對象中的數據。

private表示成員是私有的,只容許本類的成員函數和類的友元函數訪問,任何外部程序對它訪問都是非法的,全部它每每是用來描述該類對象屬性的一些數據成員,是類中被隱藏的部分。

protect表示成員是受保護類型的,與私有成員在通常狀況下含義相同,它們的區別是,在類的繼承中對產生的新類影響不一樣。

第一:private, public, protected 訪問標號的訪問範圍。
private:只能由1.該類中的函數、2.其友元函數訪問。

不能被任何其餘訪問,該類的對象也不能訪問。


protected:能夠被1.該類中的函數、2.其友元函數訪問 3.子類的函數。
但不能被該類的對象訪問。

public:能夠被1.該類中的函數、2.其友元函數訪問 3.子類的函數、也能夠由4.該類的對象訪問。
只有公有成員才能在類的外部訪問。如
class A
{
private:
int a;
public:
int b;
protected:
int c;
};
A ca;
ca.a //error
ca.b // ok
ca.c //error

class B :public A
{
public:
int d;
}

B cb;
cb.b; //ok
cb.c //error。雖然c也是B的成員,但c在被繼承的時候變成私有或者受保護的成員了。


注:
友元函數包括3種:設爲友元的普通的非成員函數;設爲友元的其餘類的成員函數;設爲友元類中的全部成員函數。

派生類的生成過程:

class employee

{

protect:

char *name; //姓名

int individualEmpNo; //我的編號

int grade; //級別

float accumPay; //月薪總額

static int employeeNo; //本公司職員編號目前最大值

public:

employee();

~employee();

void pay(); //計算月薪函數

void promote(int); //升級函數

void displayStatus(); //顯示人員信息

};

class technician:public employee

{

private:

float hourlyRate; //每小時酬金

int workHours; //當月工做時數

public:

technician(); //構造函數

void pay(); //計算月薪函數

void displayStatus(); //顯示人員信息

};

分析派生新類這個過程,其繼承和派生機制的主要目的是實現代碼的重用和擴充。實際是經歷了三個步驟:吸取基類成員、改造基類成員、添加新的成員。

1.吸取基類成員

第一步是將基類的成員全盤接收:包含了它的全部基類中除構造和析構函數以外的全部成員。

這裏派生類technician繼承了基類employee的除構造和析構函數之外的全部成員:

name; individualEmpNo; grade; accumPay; employeeNo;

pay(); promote(int); displayStatus();

通過派生過程,這些成員便存在於派生類之中。

2.改造基類函數

對基類成員的改造包括兩個方面,

一個是基類成員的訪問控制問題,主要依靠派生類聲明時的繼承方式來控制:

類的繼承方式:public、protected和private三種訪問屬性。 (見上)

第二個是對基類數據或函數成員的覆蓋,

若是派生類聲明瞭一個和某個基類成員同名的新成員(若是是成員函數,則參數表也要相同,

如pay(); displayStatus(); 參數不一樣的狀況屬於重載)派生的新成員就覆蓋了外層同名函數。這時,在派生類中或者經過派生類的對象直接使用成員名就只能訪問到派生類中聲明的同名成員,這稱爲同名覆蓋。

3.添加新的成員

咱們能夠根據實際狀況的須要,給派生類添加適當的數據和函數成員,來實現必要的新增功能。如technician派生類中的hourlyRate和workHours,在派生過程當中,因爲基類的構造函數和析構函數是不能被繼承下來的,所以咱們就須要在派生類從新加入新的構造函數和析構函數來實現一些特別的初始化和清理工做,例如派生類technician的構造函數technician();


第二:類的繼承後方法屬性變化。
特別的private,它們與派生類中新增長的private成員不一樣,派生類函數或是創建派生類對象的模塊都沒法訪問到它們。)(因此只能經過在派生類中調用基類的函數去訪問private屬性,也能夠把基類的函數用public繼承下來來訪問)


private繼承,父類的全部方法在子類中變爲private;

protected繼承,父類的protected和public方法在子類中變爲protected,private方法不變;
public繼承,父類中的方法屬性不發生改變; 原來是怎樣就怎樣
public通常爲函數和數據,protected和private通常只爲數據。
public和protected在任何方式繼承的狀況下,也能被子類函數調用。

以下所示:
public: protected: private:
public繼承 public(含繼承下來的基類函數) protected 特別的private(用派生類對象訪問時)能夠
被public繼承下來的基類函數直接調用
protected繼承 protected protected 特別的private
protected :不能被派生類對象直接調用,可間接被派生類函數和基類函數調用
特別的private:不能被派生類函數和派生類對象直接調用,(用派生類對象訪問時) 只能從新定義:調用基類 由於private不能被子類函數訪問
private繼承 private private 特別的private
private:不能被派生類對象直接調用,1.可間接被派生類函數從新定義來調用。2.基類函數調用(用派生類對象訪問時)只能從新定義:調用基類 由於public和protected能被子類函數訪問
上面爲一次繼承的狀況,如有些是沒區別的,當時若是再繼承的話就有區別了
繼承下來的訪問屬性分爲四種:
1.區分繼承與訪問, 特別的private爲不能繼承下來的,但能夠訪問
2.( private)成員:包括從基類繼承下來的非私有成員(私有繼承時),以及派生類中新增長的私有成員,在派生類內部函數均可以訪問到,但派生類對象不能訪問。
3.( protected)多是新增也多是從基類繼承過來的,派生類內部成員函數能夠訪問,當派生類對象沒法訪問。
4.(public)成員:派生類成員函數和對象都能訪問到

protected繼承和private繼承能下降訪問權限。
當類的繼承方式爲public時,
基類的public和protected成員的訪問屬性在派生類中不變,而基類的private成員仍保持私有屬性。
可得:派生類的其餘成員函數和對象能夠直接訪問基類的公有成員和保護成員。
不管是派生類的成員,仍是派生類的對象都沒法訪問基類的私有成員。
其餘外部使用者只能經過派生類的對象訪問繼承來的公有成員
公有public繼承 特別性舉例:
class vehicle
{
private:
int wheels;
protected:
float weight;
public:
vehicle(int in_wheels, float in_weight)
{  wheels=in_wheels;
weight=in_weight;
}
int get_wheels(){return wheels;}
float get_weight(){return weight;}
};
class car:public vehicle
{
private:
int passenger_load;
public:
car(int in_wheels,float in_weight,int people=5):vehicle(in_wheels,in_weight)
//這裏不是調用基類構造函數,而是初始化賦值列表。
{ passenger_load=people;}
int get_passengers(){return passenger_load;}
};
void main()
{
car bluebird(4,1000);
cout<<"The message of bluebird(wheels,weight,passengers):"<<endl;
cout<<bluebird.get_wheels()<<","
<<bluebird.get_weight()<<","
<<bluebird.get_passengers()<<endl;
}
car public繼承vehicle後,
private:wheels;
passenger_load;// 新增的
protected:weight;
public: vehicle不存在(派生類不繼承基類的構造和析構函數)
get_wheels() //能夠直接訪問
get_weight() //能夠直接訪問
car
get_passengers   ;


保護protected繼承

基類的public和protected成員都變爲保護成員,而基類的private成員不可訪問。
即基類中的保護成員只能被基類的成員函數或派生類的成員函數訪問。
舉例:
car protected繼承verhicle後,
private:wheels;
passenger_load;// 新增的
protected:weight;
vehicle不存在(派生類不繼承基類的構造和析構函數)
get_wheels()
get_weight()
public car

get_passengers ;

由於 get_wheels()  和 get_weight()被派生爲protected,其只能被被1.該類中的函數、2.其友元函數訪問 3.子類的函數。但不能被該類的對象訪問。

因此要在派生類中使用對象訪問,必須作一下修改:


class car:protected vehicle

{

private:

int passenger_load;

public:
car(int in_wheels,float in_weight,int people=5):vehicle(in_wheels,in_weight)

//這裏不是調用基類構造函數,而是初始化賦值列表。


{ passenger_load=people;}

int get_wheels (){return vehicle::get_wheels();} //從新定義get_wheels ()

float get_weight(){return weight;} //從新定義get_weight()

int get_passengers(){return passenger_load;}
};

這裏爲了保證基類的部分外部接口特徵可以在派生類中也存在,就必須在派生類中從新定義同名的成員函數 get_wheels()和get_weight(),根據同名覆蓋的原則,在主函數中天然調用的是派生類的函數。

若是使用私有繼承: 在該例子和protected同樣。

相關文章
相關標籤/搜索