數據的封裝實現了數據的隱藏,讓數據更安全,但是前面講到的通過局部變量、全局變量、類的數據成員、類的靜態成員及友元實現了數據的共享,這樣又降低了數據的安全性。有些數據是需要共享而又不能被改變的,那麼這時候我們就要將其聲明爲常量。
就像前面講到的簡單數據類型的符號常量,我們也可以用const聲明對象,叫做常對象。雞啄米這一講就給大家講講常引用、常對象和對象的常指針,另外還有常數組和常指針,這兩個概念以後雞啄米會講。
1.常引用
用const聲明的引用就是常引用。常引用所引用的對象不能被更改。我們經常見到的是常引用作爲函數的形參,這樣不會發生對實參的誤修改。常引用的聲明形式爲:const 類型說明符 &引用名。雞啄米給大家看個常引用作爲函數形參的例子:
#include<iostream>
using namespace std;
void show(const double& r);
int main()
{
double d(9.5);
how(d);
return 0;
}
void show(const double& r)
//常引用作形參,在函數中不能更新r所引用的對象。
{
cout<<r<<endl;
}
2.常對象
所謂常對象,是指數據成員在它的生存期內不會被改變。定義常對象時必須對其進行初始化,並且不能改變其數據成員的值。常對象的聲明形式爲:類名 const 對象名 或者 const 類名 對象名。常對象的例子如下:
class A
{
public:
A(int i,int j) {x=i; y=j;}
...
private:
int x,y;
};
A const a(6,8); //a是常對象,不能被更新
如果程序中出現對常對象的數據成員修改的語句,編譯器會報錯。一般修改對象的數據成員有兩種途徑,一種是通過對象名訪問公有數據成員並修改其值,而常對象的數據成員是不能被修改的;另一種是類的成員函數修改數據成員的值,而常對象不能調用普通的成員函數。可是這樣的話,常對象就只剩數據,沒有對外的接口了,這就需要爲常對象專門定義的常成員函數了。
3.類的常成員函數
類中用const聲明的成員函數就是常成員函數。常成員函數的聲明形式爲:類型說明符 函數名(參數表) const;。
雞啄米要提醒大家注意幾點:a.常成員函數在聲明和實現時都要帶const關鍵字;b.常成員函數不能修改對象的數據成員,也不能訪問類中沒有用const聲明的非常成員函數;c.常對象只能調用它的常成員函數,不能調用其他的普通成員函數;d.const關鍵字可以被用於參與對重載函數的區分,比如,如果有兩個這樣聲明的函數:void fun(); void fun() const;,則它們是重載函數。
#include<iostream>
using namespace std;
class R
{
public:
R(int r1, int r2) { R1=r1; R2=r2; }
void print();
void print() const;
private:
int R1,R2;
};
void R::print()
{
cout<<R1<<":"<<R2<<endl;
}
void R::print() const
{
cout<<R1<<";"<<R2<<endl;
}
int main()
{
R a(5,4);
a.print(); //調用void print()
const R b(20,52);
b.print(); //調用void print() const
return 0;
}
上面的R類中聲明瞭兩個同名函數print,第二個是常成員函數。在main函數中定義了兩個對象a和b,b是常對象,通過a調用的是沒有用const聲明的函數,而通過b調用的是用const聲明的常成員函數。
4.類的常數據成員
類的數據成員也可以是常量和常引用,用const聲明的數據成員就是常數據成員。在任何函數中都不能對常數據成員賦值。構造函數對常數據成員初始化,只能通過初始化列表。雞啄米給大家一個常數據成員的例子:
#include<iostream>
using namespace std;
class A
{
public:
A(int i);
void print();
const int& r;
private:
const int a;
static const int b; //靜態常數據成員
};
const int A::b=20;
A::A(int i):a(i),r(a) {}
void A::print()
{
cout<<a<<":"<<b<<":"<<r<<endl;
}
int main()
{
//建立對象a和b,並以50和10作爲初值,分別調用構造函數,通過構造函數的初始化列表給對象的常數據成員賦初值
A a1(50),a2(10);
a1.print();
a2.print();
return 0;
}
此程序的運行結果是:
50:20:50
10:20:10