参数传递和返回值的小结:
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];
};