1、C++中的const默认为内部连接,即const仅在const被定义过的文件里才是可见的,而在连接时不能被其他编译单元看到,除非使用extern显式说明为外部连接。
2、定义一个const时,必须赋一个初值给它,除非使用extern做了清楚的说明。
3、使用extern意味着使用外部连接,因此必须分配存储空间,即有几个不同的编译单元应当能够引用它,所以必须分配存储空间。
4、const可以用于聚合,但编译器不会把一个聚合保存到它的符号表中,因此必须分配存储空间。
例如:const int i[]={1,2,3,4};
float[i[1]];//错误,不能在编译期间使用它的值,因为编译器在编译期间不需要知道存储的内容
5、int*本身好像是一个离散类型,因为int*p,q;只有p是指针类型,q是整数类型,这个问题可以通过typedef来解决。因此,主张每行只定义一个指针,并尽可能在定义的时候初始化。
6、可以把一个非const对象的地址赋给一个const指针,因为也许有时候并不想改变某些可以改变的东西。然而,不能把一个const对象的地址复制给一个非const指针,因为这样做可能通过被复制的指针修改这个对象的值。
int a=1;
const int* p1=&a;//ok
const int e=1;
int* p2=&e;//not ok,但是可以强制转化过去(int*),但这样做破坏了对象的const属性以及由cosnt提供的安全性
7、char* cp="abcd";
"abcd"被编译器当做一个常量字符数组建立的,所引用该字符数组得到的结果是它在内存里的首地址,因此修改该字符数组的任何字符都会导致运行时错误。如果想要修改字符串,可以把它放在一个数组中,char cp[]="abcd";
8、函数中传递const值,如void f(const int i){},由于参数是按值传递的,因此要立即产生原变量的副本,在函数内部是不能够修改i的。
注意:void f(int a)中如果传递const值是可以的,只需要复制变量的副本给a就可以了;void f(const int a)也是可以传递非const的。区别于指针。
9、const int f(int a){
a++;
return a;
}
int b=f(1);
这样写是正确的,因为按值返回的是常量的一个副本,常量是一个临时量。
但是如果这样写的话:
const int f(int& a){
a++;
return a;
}
int b=f(1);
是错误的,因为传入的参数,会创建一个临时量,这个临时量是常量,是不能够被修改的。修改办法,int c=1;f(c);这样就行了
10、传递和返回地址
void f(char* ch){}//这样设置参数的话,将不能传递const char*,所以无论什么时候,都应该尽量使用const修饰它。
11、const char* v(){
return "result of function v()";
}
返回一个从字符数组的字面值中建立的const char*。在编译器建立了它并把它存储在静态存储区后,这个声明实际上产生了这个字符数组的字面值的地址。
12、把一个临时对象传递给接受const引用的函数是可能的,但不能把一个临时对象传递给接受指针的函数,因为对于指针,必须明确的接受地址。因此,一个const的临时变量,它的地址可以被传递给一个函数,这个函数的参数必须是const。
class X{};
X f() { return X();}
void g1(X&){}
void g2(const X&){}
g1(f());//not ok,参数必须是const引用才行,因为临时变量为常量
g2(f());//ok
//==========================================================================================================================
类中的const
1、class A{
const int size=2;
}
这样写的话,编译器会报错,说size不是静态的。size在每个对象里分配存储并代表一个值,这个值一旦被初始化就不能被改变。在一个类里使用const意味着“在这个对象生命期内,它是一个常量”,然而,对这个常量来讲,每个不同的对象可以含有一个不同的值。因此,编译器拒绝直接给size赋值的写法,才能支持每个对象不同的size值。
正确的写法是:
class A{
const int size;
public:
A(int m):size(m){}
}
2、如何让一个类具有编译期间的常量成员
使用static关键字,表示不管类对象创建多少次,都只有一个实例
class A{
static const int m;
}
const int A::m=3;//正确
int main(){
const int A::m=3;//错误,初始化需要在上面初始化,而且只能初始化一次。
}
其实上面的过程其实就是直接在类A中static const int m=3;就可以了。
3、const成员函数
const 成员函数只能对于const对象的调用,一个没有被声明为const的成员函数被看成是将要修改对象中数据成员的函数,而且编译器不允许它被const对象所调用。