C++ const关键字
1.如果函数的形参是指向非const型变量的指针,则实参只能用指向非const变量的指针,而不能指向const变量的指针,这样在执行函数的过程中可以改变形参指针变量所指向的值,如果函数的形参指向const型变量的指针,则在执行函数的过程中显然不能改变指针变量所指向变量的值,因此允许实参是指向const或者非const变量的指针。
2.在定义类对象的时候,如果对象指定为常对像,常对像的数据成员必须有初始值,即成员变量必须初始化。如过一个对象被声明为常对像,则不能调用该对象的非const型成员函数,除了由系统调用的隐式构造函数和析构函数。如果定义了一个const对象,只能调用其中的const成员函数,不能调用非const成员函数。另外,const成员函数不能调用另一个非const成员函数。
3.类的const成员函数和非const成员函数都可以引用类的非const数据成员,但是const成员函数不能改变其值,对于const数据成员,不论是const成员函数或者非const成员函数都可以引用,但都不能改变其值,当类的对象为const对象的时候,非const成员函数不能引用const数据成员,也不能修改其值,const成员函数可以引用const数据成员,但是不能改变其值。
4.不能用非const指针指向一个const变量,比如:
const int a = 1;
int *p = &a; //初始化”: 无法从“const int *”转换为“int *”
可以用一个指向常变量的指针或者指向变量的常指针来指向一个const变量,比如:
const int a = 1;
const int *p = &a;
或者:
const int a = 1;
int const *p = &a;
5.假设给出一下语句:
typedef string *pstring;
const pstring cstr;
从表面上看,此语句等同于const string *pstring;但是情况却不是这样子的,此语句等同于string *const cstr;因为const修饰的是pstring的类型,这就是一个指针,该语句是把cstr定义为指向string类型对象的常指针。
6.普通引用不能绑定到const变量,但是const引用可以绑定到非const变量。const引用一旦绑定到非const对象,就不能通过const引用来改变非const变量的值,但是可以通过对非const变量本身的赋值来改变其值,代码如下:
int a = 1;
const int &b = a;
a = 2;
printf("%d\n", b);
运行结果:
7.不能将一个const变量的地址赋给一个非const变量的指针,比如:
const char c = 'a';
char *d = &c;//error
如果一定要这样做的话怎么办呢?代码如下:
const char c = 'a';
char *d = const_cast<char*>(&c);
8.const成员函数中无法修改类的成员变量的值,如果希望修改成员变量的值的话,可以在变量之前加上mutable关键字,代码如下:
class Fred
{
public:
void inspect() const;
private:
mutable int intValue;
};
void Fred::inspect() const
{
intValue = 100;
}
9.const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。如:
class A
{
const int size = 100; //错误
int array[size]; //错误,未知的size
}
const数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现。如
class A
{
enum {size1=100, size2 = 200 };
int array1[size1];
int array2[size2];
}
枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。
10.在C++中可以通过使用const来实现函数的重载,代码如下:
class A
{
public:
void fun(int &a)
{
cout<<"a = "<<a<<" ";
cout<<"fun(int &a)"<<endl;
}
void fun(const int &a)
{
cout<<"a = "<<a<<" ";
cout<<"fun(const int &a)"<<endl;
}
void fun(int *a)
{
cout<<"a = "<<*a<<" ";
cout<<"fun(int *&a)"<<endl;
}
void fun(const int *a)
{
cout<<"a = "<<*a<<" ";
cout<<"fun(const int *&a)"<<endl;
}
void fun()
{
cout<<"fun()"<<endl;
}
void fun()const
{
cout<<"fun()const"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1;
const int b = 2;
A objA;
objA.fun(a);
objA.fun(b);
objA.fun(&a);
objA.fun(&b);
const A const_objA;
objA.fun();
const_objA.fun();
return 0;
}
运行结果: