参数传递和返回值的小结:
void t( int * ) {} 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)常量,这里用到了构造函数初始化列表,它出现在函数参数表和冒号后但在构造函数主体开头的花括号前。
class Hony{ 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 定义的地方对它初始化。
#include < string > 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。
class Bunch{ enum { size = 1000 ; } int i[size];}; 这里使用的enum不占用对象的存储空间,在编译期间得到枚举值。
