參數傳遞和返回值的小結:
void u(const int *p)
{
*p=2; //error
int i=*p; //OK
int* p2=p; //error
}
const char* v()
{
return "result of function v";
}
const int* const w()
{
static int i;
return &i;
}
int main()
{
int x=0;
int *ip=&x;
const int *cip=&x;
t(ip); //OK
t(cip); //error
u(ip); //OK
u(cip); //OK
char* cp=v(); //error
const char *ccp=v(); //OK
int *ip2=w(); //error
const int* const ccip=w(); //OK
const int* cip2=w(); //OK
*w()=1; //error
}
函數t 可以用const和非const 指針做參數,而函數u 只能用const指針作爲參數,而且編譯器也不允許使用存儲在const指針裏的地址來建立一個非const指針。
函數v 返回的是常量的字符數組,編譯器把它儲存在靜態存儲區裏,所以返回是安全的。
函數w 返回值要求這個指針和指針所指向的對象均爲常量。首先變量i 是靜態的,返回後也是有效的地址。但在後面main函數的測試裏發現w的返回值可以賦給const int* ,其實這並不矛盾,因爲這時w的返回值是當右值來使用的,只有當它用成左值時纔會出問題,就像最後一行。
標準參數傳遞:
在C++裏面,對於用戶自定義對象我們通常是按引用的方式來傳遞,但需要注意的一點就是,把一個臨時對象傳遞給接受const引用的函數是可能的,但不能把一個臨時對象傳遞給接受指針的函數。
類裏的常量:
1.const 成員
我們如果要在類裏面建立一個數組,就需要用const代替#define設置數組大小,這時使用的const意味 着"在這個對象生命期內,它是一個常量"。然而,對這個常量來講,每個不同的對象可以含有一個不同的值。這樣就出現了一個問題,什麼時候初始化這個(非static)常量,這裏用到了構造函數初始化列表,它出現在函數參數表和冒號後但在構造函數主體開頭的花括號前。
{
const int size;
public:
Hony(int sz);
void print();
};
Hony::Hony(int sz): size(sz) {}
void Hony::print() { cout<<size<<endl; }
int main()
{
Hony a(1),b(2),c(3);
a.print(),b.print(),c.print();
}
2.編譯期間類裏的常量(靜態常量)
還有一種情況就是,如何讓一個類有編譯期間的常量成員?這裏就需要用關鍵字static ,"不管類的對象被創建多少次,都只有一個實例",而且必須在static const 定義的地方對它初始化。
class StringStack
{
static const int size=100;
const string* stack[size];
int index;
public:
StringStack();
void push(const string* s);
const string* pop();
};
這裏只給出了類的聲明,不過可以看出static const 是怎麼用的。
3. 舊代碼中的"enum hack"
在舊版本C++中,不支持在類中使用static const。另外有種典型的解決辦法,使用不帶實例的無標記enum。
{
enum { size=1000; }
int i[size];
};