深入理解C++中public、protected及private用法
初學(xué)C++的朋友經(jīng)常在類(lèi)中看到public,protected,private以及它們?cè)诶^承中表示的一些訪(fǎng)問(wèn)范圍,很容易搞糊涂。今天本文就來(lái)十分分析一下C++中public、protected及private用法。相信對(duì)于大家深入掌握C++程序設(shè)計(jì)會(huì)有很大的幫助。
這里我們首先要明白下面幾點(diǎn)。
1.類(lèi)的一個(gè)特征就是封裝,public和private作用就是實(shí)現(xiàn)這一目的。所以:
用戶(hù)代碼(類(lèi)外)可以訪(fǎng)問(wèn)public成員而不能訪(fǎng)問(wèn)private成員;private成員只能由類(lèi)成員(類(lèi)內(nèi))和友元訪(fǎng)問(wèn)。
2.類(lèi)的另一個(gè)特征就是繼承,protected的作用就是實(shí)現(xiàn)這一目的。所以:
protected成員可以被派生類(lèi)對(duì)象訪(fǎng)問(wèn),不能被用戶(hù)代碼(類(lèi)外)訪(fǎng)問(wèn)。
現(xiàn)來(lái)看看如下示例:
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正確
cout << a1 << endl; //正確
cout << a2 << endl; //正確,類(lèi)內(nèi)訪(fǎng)問(wèn)
cout << a3 << endl; //正確,類(lèi)內(nèi)訪(fǎng)問(wèn)
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
int main(){
A itema;
itema.a = 10; //正確
itema.a1 = 20; //正確
itema.a2 = 30; //錯(cuò)誤,類(lèi)外不能訪(fǎng)問(wèn)protected成員
itema.a3 = 40; //錯(cuò)誤,類(lèi)外不能訪(fǎng)問(wèn)private成員
system("pause");
return 0;
}
繼承中的特點(diǎn):
先記?。翰还苁欠窭^承,上面的規(guī)則永遠(yuǎn)適用!
有public, protected, private三種繼承方式,它們相應(yīng)地改變了基類(lèi)成員的訪(fǎng)問(wèn)屬性。
1.public繼承:基類(lèi)public成員,protected成員,private成員的訪(fǎng)問(wèn)屬性在派生類(lèi)中分別變成:public, protected, private
2.protected繼承:基類(lèi)public成員,protected成員,private成員的訪(fǎng)問(wèn)屬性在派生類(lèi)中分別變成:protected, protected, private
3.private繼承:基類(lèi)public成員,protected成員,private成員的訪(fǎng)問(wèn)屬性在派生類(lèi)中分別變成:private, private, private
但無(wú)論哪種繼承方式,上面兩點(diǎn)都沒(méi)有改變:
1.private成員只能被本類(lèi)成員(類(lèi)內(nèi))和友元訪(fǎng)問(wèn),不能被派生類(lèi)訪(fǎng)問(wèn);
2.protected成員可以被派生類(lèi)訪(fǎng)問(wèn)。
再來(lái)看看以下代碼:
1.public繼承
代碼如下:
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正確
cout << a1 << endl; //正確
cout << a2 << endl; //正確
cout << a3 << endl; //正確
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : public A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正確,public成員
cout << a1 << endl; //正確,基類(lèi)的public成員,在派生類(lèi)中仍是public成員。
cout << a2 << endl; //正確,基類(lèi)的protected成員,在派生類(lèi)中仍是protected可以被派生類(lèi)訪(fǎng)問(wèn)。
cout << a3 << endl; //錯(cuò)誤,基類(lèi)的private成員不能被派生類(lèi)訪(fǎng)問(wèn)。
}
};
int main(){
B b(10);
cout << b.a << endl;
cout << b.a1 << endl; //正確
cout << b.a2 << endl; //錯(cuò)誤,類(lèi)外不能訪(fǎng)問(wèn)protected成員
cout << b.a3 << endl; //錯(cuò)誤,類(lèi)外不能訪(fǎng)問(wèn)private成員
system("pause");
return 0;
}
2.protected繼承:
代碼如下:
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正確
cout << a1 << endl; //正確
cout << a2 << endl; //正確
cout << a3 << endl; //正確
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : protected A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正確,public成員。
cout << a1 << endl; //正確,基類(lèi)的public成員,在派生類(lèi)中變成了protected,可以被派生類(lèi)訪(fǎng)問(wèn)。
cout << a2 << endl; //正確,基類(lèi)的protected成員,在派生類(lèi)中還是protected,可以被派生類(lèi)訪(fǎng)問(wèn)。
cout << a3 << endl; //錯(cuò)誤,基類(lèi)的private成員不能被派生類(lèi)訪(fǎng)問(wèn)。
}
};
int main(){
B b(10);
cout << b.a << endl; //正確。public成員
cout << b.a1 << endl; //錯(cuò)誤,protected成員不能在類(lèi)外訪(fǎng)問(wèn)。
cout << b.a2 << endl; //錯(cuò)誤,protected成員不能在類(lèi)外訪(fǎng)問(wèn)。
cout << b.a3 << endl; //錯(cuò)誤,private成員不能在類(lèi)外訪(fǎng)問(wèn)。
system("pause");
return 0;
}
3.private繼承:
代碼如下:
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正確
cout << a1 << endl; //正確
cout << a2 << endl; //正確
cout << a3 << endl; //正確
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : private A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正確,public成員。
cout << a1 << endl; //正確,基類(lèi)public成員,在派生類(lèi)中變成了private,可以被派生類(lèi)訪(fǎng)問(wèn)。
cout << a2 << endl; //正確,基類(lèi)的protected成員,在派生類(lèi)中變成了private,可以被派生類(lèi)訪(fǎng)問(wèn)。
cout << a3 << endl; //錯(cuò)誤,基類(lèi)的private成員不能被派生類(lèi)訪(fǎng)問(wèn)。
}
};
int main(){
B b(10);
cout << b.a << endl; //正確。public成員
cout << b.a1 << endl; //錯(cuò)誤,private成員不能在類(lèi)外訪(fǎng)問(wèn)。
cout << b.a2 << endl; //錯(cuò)誤, private成員不能在類(lèi)外訪(fǎng)問(wèn)。
cout << b.a3 << endl; //錯(cuò)誤,private成員不能在類(lèi)外訪(fǎng)問(wèn)。
system("pause");
return 0;
}
通過(guò)以上的代碼都備有較為詳盡的注釋?zhuān)x者應(yīng)該能夠理解。仔細(xì)看代碼中派生類(lèi)B中定義了和基類(lèi)同名的成員a,此時(shí)基類(lèi)的a仍然存在,可以驗(yàn)證。
int main(){
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
system("pause");
return 0;
}
輸出:
16
20
所以派生類(lèi)包含了基類(lèi)所有成員以及新增的成員,同名的成員被隱藏起來(lái),調(diào)用的時(shí)候只會(huì)調(diào)用派生類(lèi)中的成員。
如果要調(diào)用基類(lèi)的同名成員,可以用以下方法:
int main(){
B b(10);
cout << b.a << endl;
cout << b.A::a << endl;
system("pause");
return 0;
}
輸出:
10
4
記得這里是在類(lèi)外訪(fǎng)問(wèn),而a在基類(lèi)中是public,所以繼承方式應(yīng)該為public,使得a在派生類(lèi)中仍然為public,在類(lèi)外可以訪(fǎng)問(wèn)。
感興趣的讀者可以調(diào)試運(yùn)行一下本文實(shí)例,加深印象的同時(shí)還會(huì)有新的收獲。
相關(guān)文章
C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷方法實(shí)例總結(jié)
這篇文章主要介紹了C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷方法實(shí)例總結(jié),是算法設(shè)計(jì)中比較經(jīng)典的一個(gè)遍歷算法,需要的朋友可以參考下2014-08-08
C++語(yǔ)言實(shí)現(xiàn)線(xiàn)性表之?dāng)?shù)組實(shí)例
這篇文章主要介紹了C++語(yǔ)言實(shí)現(xiàn)線(xiàn)性表之?dāng)?shù)組,實(shí)例分析了C++實(shí)現(xiàn)數(shù)組形式線(xiàn)性表的原理與方法,需要的朋友可以參考下2015-04-04

