數(shù)據(jù)封裝是面向?qū)ο缶幊痰囊粋€(gè)重要特點(diǎn),它防止函數(shù)直接訪問類類型的內(nèi)部成員。
類成員的訪問限制是通過在類主體內(nèi)部對(duì)各個(gè)區(qū)域標(biāo)記 public峭梳、private持偏、protected 來指定的。關(guān)鍵字 public痹筛、private莺治、protected 稱為訪問修飾符廓鞠。
一個(gè)類可以有多個(gè) public、protected 或 private 標(biāo)記區(qū)域谣旁。每個(gè)標(biāo)記區(qū)域在下一個(gè)標(biāo)記區(qū)域開始之前或者在遇到類主體結(jié)束右括號(hào)之前都是有效的床佳。成員和類的默認(rèn)訪問修飾符是 private。
class Base {
public:
// 公有成員
protected:
// 受保護(hù)成員
private:
// 私有成員
};
公有(public)成員
公有成員在程序中類的外部是可訪問的榄审。您可以不使用任何成員函數(shù)來設(shè)置和獲取公有變量的值砌们,如下所示:
實(shí)例
#include <iostream>
using namespace std;
class Line
{
public:
double length;
void setLength( double len );
double getLength( void );
};
// 成員函數(shù)定義
double Line::getLength(void)
{
return length ;
}
void Line::setLength( double len )
{
length = len;
}
// 程序的主函數(shù)
int main( )
{
Line line;
// 設(shè)置長度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
// 不使用成員函數(shù)設(shè)置長度
line.length = 10.0; // OK: 因?yàn)?length 是公有的
cout << "Length of line : " << line.length <<endl;
return 0;
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
Length of line : 6
Length of line : 10
私有(private)成員
私有成員變量或函數(shù)在類的外部是不可訪問的搁进,甚至是不可查看的怨绣。
只有類和友元函數(shù)可以訪問私有成員。
默認(rèn)情況下拷获,類的所有成員都是私有的篮撑。例如在下面的類中,width 是一個(gè)私有成員匆瓜,這意味著赢笨,如果您沒有使用任何訪問修飾符,類的成員將被假定為私有成員:
實(shí)例
class Box
{
double width;
public:
double length;
void setWidth( double wid );
double getWidth( void );
};
實(shí)際操作中驮吱,我們一般會(huì)在私有區(qū)域定義數(shù)據(jù)茧妒,在公有區(qū)域定義相關(guān)的函數(shù),以便在類的外部也可以調(diào)用這些函數(shù)左冬,如下所示:
實(shí)例
#include <iostream>
using namespace std;
class Box
{
public:
double length;
void setWidth( double wid );
double getWidth( void );
private:
double width;
};
// 成員函數(shù)定義
double Box::getWidth(void)
{
return width ;
}
void Box::setWidth( double wid )
{
width = wid;
}
// 程序的主函數(shù)
int main( )
{
Box box;
// 不使用成員函數(shù)設(shè)置長度
box.length = 10.0; // OK: 因?yàn)?length 是公有的
cout << "Length of box : " << box.length <<endl;
// 不使用成員函數(shù)設(shè)置寬度
// box.width = 10.0; // Error: 因?yàn)?width 是私有的
box.setWidth(10.0); // 使用成員函數(shù)設(shè)置寬度
cout << "Width of box : " << box.getWidth() <<endl;
return 0;
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí)桐筏,它會(huì)產(chǎn)生下列結(jié)果:
Length of box : 10
Width of box : 10
保護(hù)(protected)成員
保護(hù)成員變量或函數(shù)與私有成員十分相似,但有一點(diǎn)不同拇砰,保護(hù)成員在派生類(即子類)中是可訪問的梅忌。
在下一個(gè)章節(jié)中,您將學(xué)習(xí)到派生類和繼承的知識(shí)〕疲現(xiàn)在您可以看到下面的實(shí)例中牧氮,我們從父類 Box 派生了一個(gè)子類 smallBox。
下面的實(shí)例與前面的實(shí)例類似瑰枫,在這里 width 成員可被派生類 smallBox 的任何成員函數(shù)訪問踱葛。
實(shí)例
#include <iostream>
using namespace std;
class Box
{
protected:
double width;
};
class SmallBox:Box // SmallBox 是派生類
{
public:
void setSmallWidth( double wid );
double getSmallWidth( void );
};
// 子類的成員函數(shù)
double SmallBox::getSmallWidth(void)
{
return width ;
}
void SmallBox::setSmallWidth( double wid )
{
width = wid;
}
// 程序的主函數(shù)
int main( )
{
SmallBox box;
// 使用成員函數(shù)設(shè)置寬度
box.setSmallWidth(5.0);
cout << "Width of box : "<< box.getSmallWidth() << endl;
return 0;
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
Width of box : 5
繼承中的特點(diǎn)
有public, protected, private三種繼承方式光坝,它們相應(yīng)地改變了基類成員的訪問屬性尸诽。
public 繼承:
基類 public 成員,protected 成員盯另,private 成員的訪問屬性在派生類中分別變成:public, protected, privateprotected 繼承:
基類public 成員性含,protected 成員,private 成員的訪問屬性在派生類中分別變成:protected, protected, privateprivate 繼承:
基類 public 成員土铺,protected 成員胶滋,private 成員的訪問屬性在派生類中分別變成:private, private, private
但無論哪種繼承方式板鬓,上面兩點(diǎn)都沒有改變:
- private 成員只能被本類成員(類內(nèi))和友元訪問,不能被派生類訪問究恤;
- protected 成員可以被派生類訪問俭令。
public 繼承
實(shí)例
#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; //正確部宿,基類的public成員抄腔,在派生類中仍是public成員。
cout << a2 << endl; //正確理张,基類的protected成員赫蛇,在派生類中仍是protected可以被派生類訪問。
cout << a3 << endl; //錯(cuò)誤雾叭,基類的private成員不能被派生類訪問悟耘。
}
};
int main(){
B b(10);
cout << b.a << endl;
cout << b.a1 << endl; //正確
cout << b.a2 << endl; //錯(cuò)誤,類外不能訪問protected成員
cout << b.a3 << endl; //錯(cuò)誤织狐,類外不能訪問private成員
system("pause");
return 0;
}
protected 繼承
實(shí)例
#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; //正確移迫,基類的public成員旺嬉,在派生類中變成了protected,可以被派生類訪問厨埋。
cout << a2 << endl; //正確邪媳,基類的protected成員,在派生類中還是protected荡陷,可以被派生類訪問雨效。
cout << a3 << endl; //錯(cuò)誤,基類的private成員不能被派生類訪問亲善。
}
};
int main(){
B b(10);
cout << b.a << endl; //正確设易。public成員
cout << b.a1 << endl; //錯(cuò)誤,protected成員不能在類外訪問蛹头。
cout << b.a2 << endl; //錯(cuò)誤,protected成員不能在類外訪問戏溺。
cout << b.a3 << endl; //錯(cuò)誤渣蜗,private成員不能在類外訪問。
system("pause");
return 0;
}
private 繼承
實(shí)例
#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; //正確,基類public成員,在派生類中變成了private,可以被派生類訪問托享。
cout << a2 << endl; //正確骚烧,基類的protected成員浸赫,在派生類中變成了private,可以被派生類訪問。
cout << a3 << endl; //錯(cuò)誤赃绊,基類的private成員不能被派生類訪問既峡。
}
};
int main(){
B b(10);
cout << b.a << endl; //正確。public成員
cout << b.a1 << endl; //錯(cuò)誤碧查,private成員不能在類外訪問运敢。
cout << b.a2 << endl; //錯(cuò)誤, private成員不能在類外訪問。
cout << b.a3 << endl; //錯(cuò)誤忠售,private成員不能在類外訪問传惠。
system("pause");
return 0;
}
代碼鏈接:https://github.com/karst87/cpp/tree/master/learning/com.runoob