Const关键字用法
1. Const修饰的变量 (变量命名所有字母全部大写)
1.1 值类型
举例: const double PI = 3.1415; // 必须在定义时进行初始化,且不能再修改它的值
1.2 指针类型
1.2.1 指向常量的指针(只读指针,指针常量)
int int1 = 1, int2 = 2;
const int* pointerConst; //定义一个指向整形常量的指针
pointerConst = &int1; //pointerConst指向int1,
cout<<*pointerConst<<endl; //输出为 1,*pointerConst可以读取int1中的值
*pointerConst = 100; //ERROR : 错误,不能修改指向地址中的值
pointerConst = &int2 ; // 可以修改pointerConst指向的地址
备注: 在pointerConst = &int2后面,对int2进行修改, int2 = 100的操作是允许的,同样在修改Int2的值为100后,*pointerConst的读取值也同样为100, 所以称为只读指针的原因。
用法: 在C++中,结构体和类型数据的传递默认为值传递。
值传递,可以保证实参数据的安全,代价是 实参的值拷贝到形参中的开销
指针传递(引用传递),可以直接调用在内存中实参的值,省去了拷贝的开销, 代价是 实参可能在被调用函数中修改。
所以: 只读指针, 即能直接调用实参的值,又可以保证实参不被修改。
1.2.2 常量指针
指针指向确定的地址, 指针指向的地址不修改; 地址中的值可以通过指针进行间接修改
举例:
int int1 = 1, int2 = 2;
int* const constPointer0 = new(int); //定义常量指针,必须初始化; 在这里是为其申请一个整形的地址
int* const constPointer1 = &int1; //同样也可以用一个变量的地址进行初始化
*constPointer0 = 3.1415; //可以通过指针修改地址中的值
*constPointer1 = 45; //也是可以的
constPointer0 = &int1; //ERROR: 不能修改指针指向的地址
constPointer1 = &int2; //ERROR: 不能修改指针指向的地址
1.2.3 const [Type]* const指针
指针指向的地址确定(必须在声明的时候初始化),且地址中的值不能通过指针进行间接的修改
举例:
int int1 = 1, int2 = 2;
const int* const intPtr = &int1;
intPtr = &int2; //ERROR
*intPtr = 100; //ERROR
1.3 引用类型
举例:
int1 = 1;
const int& int1Ref = int1;//声明一个常量的引用
int1Ref = 100; //ERROR : 不能进行任何修改操作
备注:见下面的函数头部声明
void function1(int* intPtr);
void function1(int& intRef);
在函数调用时,第一个函数传递的是地址,第二个传递的是变量,但是所有的修改操作都会对实参有影响,都可以节省参数拷贝的花销.
声明为Const的引用的用法和Const指针的优缺点是一样的;
2.const修饰的数据成员
2.1 const数据成员的定义和初始化
举例:
class Type
{
public:
Type(int value1, int value2):publicConstInt(value1), privateConstInt(value2) { }
const publicConstInt;
private:
const privateConstInt;
}
上面的代码定义两个Const的数据成员,Const修饰的数据成员的值都不能再初始化以后进行修改, 也就是在构造函数参数列表里进行初始化.
有Const数据成员的类,必须在构造函数中提供该成员的初始化值,初始化的方法:
构造函数名称(参数1,参数2, ……):const数据字段名称1(初始化值1), const数据字段名称2(初始化值2),……{ }
备注: "const数据字段名称1(初始化值1)“ 编译器就会初始化const数据字段,不用再构造函数类型再进行“=”的赋值运算了。
2.2
3.const成员函数
3.1 const成员函数定义
举例:
class Type
{
public:
int Function() { }; //公有成员函数
int* PtrFucntion() {} //公有成员函数,返回Int指针的函数
const int* constPtrFunction() { }; //返回类型为 consti int*的成员函数
int FunctionConst() const { }; //const成员函数
int Function() const { }; //重载, 用const重载第一个函数
private:
}
int* PtrFunction() 和 const int* constPtrFucntion()的区别:看下面代码调用
*PtrFunction() = 100; //可以赋值,因为返回的是一个整形的指针,对返回的指针进行取地址运算,再赋值
*constPtrFunction() = 100;//不可以复制,因为返回的是 const int * const 指针
Int FunctionConst() const 成员函数:
1. const成员函数,只能是出现在类中的成员函数,const 关键字出现在 "()" 和 "{}" 之间;
2. const成员函数中对所有类中的数据成员(包括公有和私有数据成员)的修改都是非法的;
3. const成员函数中不能调用非const成员函数
4. const成员函数可以对类中的函数进行重载;( --- 为什么下面会说明)
5. const成员函数的声明和定义分开时,都需要加上const的关键字
备注:成员函数只能在类中进行定义和声明,在其他地方的声明和定义都是非法的;
Attention:以上说的 " const成员函数中对所有类中的数据成员(包括公有和私有数据成员)的修改都是非法的";
这里说的修改包括直接修改和间接修改,直接修改也就是通常说的赋值操作,间接修改可以通过调用其他函数进行修改:比如私有函数,进行修改。所以说“const成员函数中不能调用非const成员函数”;
4.const对象
举例:
const Class class1;
只能调用所有的公有数据成员 和 所有声明为const的成员函数,其他的调用和访问都可能对数据进行修改,所以调用是非法的;