常型別(C++學習筆記 30)
阿新 • • 發佈:2018-12-09
因為程式中各種形式的資料共享,在不同程度上破壞了資料的安全性。引入常型別的目的是,為了保證資料共享又防止資料被改動。
常型別是指使用型別修飾符 const 說明的型別,常型別的變數或物件成員的值在程式執行期間是不可改變的。
本文將從三方面入手:常引用、常物件和常物件成員。
一、常引用
- 常引用: 在說明引用時用 const 修飾的引用。
- 如果用 常引用作形參,便不會產生對實參的不希望的更改。
- 常引用的說明形式:
const 型別 &引用名;
例如:
int a=5;
const int &b=a;
其中,b 是一個常引用,它所引用的物件不允許更改。如果出現:b=22;
例 1:常引用作函式引數。
在實際應用中,常引用往往用來作函式的形參,這樣的引數稱為 常引數。
用常引用作形參,能夠避免對實參的更改,保證資料的安全。
#include<iostream>
using namespace std;
int add(const int &i,const int &j); //函式 add 的形參是常引用
int main(){
int a=20;
int b=30;
cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
a= 15;
b=50;
cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
return 0;
}
int add(const int &i,const int &j){
//i=i+50; //不允許改變 i 的值,error是 assignment of read-only reference 'i' 即 給只讀引用值'i'賦值出現錯誤
return i+j;
}
二、常物件
- 常物件:在說明物件時用 const 修飾。
- 常物件的資料成員值在物件的整個生存期內不能被改變。
- 常物件的說明形式:
類名 const 物件名[(引數表)];
或者
const 類名 物件名[(引數表)]
在定義物件時必須進行初始化,而且不能被更新。
例 2:常物件 和 非 常物件 的比較
#include<iostream>
using namespace std;
class Sample{
public:
int m;
Sample(int i,int j){
m=i;
n=j;
}
void setvalue(int i){
n=i;
}
void display(){
cout<<"m="<<m<<endl;
cout<<"n="<<n<<endl;
}
private:
int n;
};
int main(){
Sample a(10,20);
a.setvalue(40);
a.m=30;
a.display();
return 0;
}
在例 2 中,物件 a 是一個普通的物件,而不是常物件,執行結果為:
若將上述的物件 a 定義為常物件,主函式修改一下:
int main(){
const Sample a(10,20); //a 是常物件,而不是普通物件
a.setvalue(40); //錯誤:不允許改變常物件的資料成員值
a.m=30; //錯誤:不允許改變常物件的資料成員值
a.display(); //錯誤:不允許常物件呼叫普通的成員函式
return 0;
}
則會出現三處錯誤(要格外注意,第三處錯誤,不允許常物件呼叫普通的成員函式)。
三、常物件成員
1、常資料成員
- 類的資料成員可以是常量或常引用,使用 const 說明的資料成員稱為 常資料成員。
- 如果在一個類中說明了常資料成員,那麼建構函式就只能通過成員初始化列表對該資料成員進行初始化,在建構函式的函式體內對常資料成員賦初值也是非法的,而且其他任何函式都不能對該成員賦值。
- 一旦對某物件的常資料成員初始化後,該資料成員的值是不能改變的,但不同物件中的該資料成員的值可以是不同的(在定義物件時給出)。
例 4:常資料成員的使用。
#include<iostream>
using namespace std;
class Date{
public:
Date(int y,int m,int d);
void showDate();
private:
const int year; //常資料成員
const int month;
const int day;
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){
}
void Date::showDate(){
cout<<year<<"."<<month<<"."<<day<<endl;
}
int main(){
Date date1(2018,11,25);
date1.showDate();
return 0;
}
2、常成員函式
- 在類中使用關鍵字 const 說明的成員函式為常成員函式。
- 常成員函式的說明格式如下:
型別說明符 函式名(引數表) const;
const是函式型別的一個組成部分,因此在宣告和定義函式時都要有關鍵字 const,在呼叫時不必加 const。
例 5:常成員函式的使用(仔細看程式碼)。
#include<iostream>
using namespace std;
class Date{
public:
Date(int y,int m,int d);
void showDate(); //宣告普通的成員函式 showDate
void showDate() const; //宣告常成員函式 showDate
private:
int year;
int month;
int day;
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){
}
void Date::showDate(){
cout<<"showDate1:"<<endl;
cout<<year<<"."<<month<<"."<<day<<endl;
}
void Date::showDate() const{
cout<<"showDate2:"<<endl;
cout<<year<<"."<<month<<"."<<day<<endl;
}
int main(){
Date date1(2018,11,25); //定義普通物件 date1
date1.showDate();
const Date date2(2018,9,28); //定義常物件 date2
date2.showDate();
return 0;
}
執行結果:
在例 5中類 Date 說明了兩個同名的成員函式 showDate,一個是普通的成員函式,另一個是常成員函式,它們是過載的(關鍵字 const 可以被用於區分過載函式)。
在主函式中說明了兩個物件 date1 和 date2,其中物件 date2 是常物件。通過物件 date1 呼叫的是沒有用 const 修飾的成員函式 showDate,而通過物件 date2 呼叫的是用 const 修飾的常成員函式 showDate。
說明注意:
(1)常成員函式可以訪問常資料成員,也可以訪問普通資料成員。
資料成員 | 普通成員函式 | 常成員函式 |
---|---|---|
普通資料成員 | 可以訪問,也可以改變值 | 可以訪問,但不可以改變 |
常資料成員 | 可以訪問,但不可以改變值 | 可以訪問,但不可以改變 |
常物件的資料成員 | 不允許訪問和改變值 | 可以訪問,但不可以改變 |
(2)如果將一個物件說明為常物件,則通過該物件只能呼叫它的常成員函式,而不能呼叫普通的成員函式。所以說,常成員函式是常物件唯一的對外介面,這是C++從語法機制上對常物件的保護。
(3)常成員函式不能更新物件的資料成員,也不能呼叫該類中的普通成員函式,這就保證了在常成員函式中絕對不會更新資料成員的值。