C++ : const关键字

        const关键字并不是表示常量,而是表示“内容不可修改”。const修饰的变量并不一定是值保持不变的,可能由编译器检测不到的外部条件改变,const可以和volatile同时修饰一个变量。

        const与#define相比较是面试中常见的问题。#define定义常量,由预处理器进行字符替换,编译器不进行类型安全检查。const定义的是一个值恒定的变量,编译器会对其进行类型安全检查。在C++中推荐用const替代#define宏定义常量。


//xk> const对象的作用域

        在C语言中,const对象默认是外部连接的,即const对象的名字是全局的。C++中,const对象默认是内部连接的,即作用域仅在定义const对象的文件中。

// 这样写在C++中是错误的。const对象必须在定义时初始化。
// 但是在C中是正确的,C编译器仅把它当做一个声明。
const int val1;

// C++中声明const对象必须显式地用extern
extern const int val2;
// C++中默认const为内部连接。有初始化式表示是定义而非声明,extern显式声明为外部连接
extern const int val3 = 100;
        C编译器不能将const对象看成一个编译期间的常量。而C++想要用const替代#define,自然会尽量把const对象当成编译期常量(专业术语叫常量表达式,注意并非所有const对象都是编译期常量)。因此,下面这样写在C中是错误的,但是在C++中是常见的。
const int bufsize = 100;
char buf[bufsize];


//xk> const指针和指向const对象的指针


//xk> const引用


//xk> const修饰函数参数


//xk> const修饰函数返回值


//xk> const修饰成员函数

        将const关键字加在成员函数的形参表之后,表示这是一个const成员,不能修改其所操作的对象的数据成员(用关键字mutable修饰的数据成员除外,mutable关键字就是用于在const成员函数中修改某个数据成员)。例如:

class myClass{
public:
    double myFunc(int a, int b) const;
};

double
myClass::myFunc(int a, int b) const
{
    // 从这也可以看出,函数体的{还是另起一行比较好。跟在const后面别扭
}

        注意:const必须同时出现在成员函数的声明和定义处,否则编译报错。

//xk> const成员变量


//xk> const与重载

        如果函数形参不是引用或指针,则const版本与non-const版本不能构成重载。

// 编译报错:函数重定义。形参不是引用或指针,不能基于const重载
int myFunc(int a){}
int myFunc(const int a){} // PS:在一个作用域中就能构成重载,不要求是成员函数
原因在于实参传递的方式,用实参初始化形参时并不考虑形参是否为const,函数操纵的只是副本,无法改变实参。将一个const实参传给const形参或non-const形参没有本质区别。

        如果函数形参是引用或指针,则形参为指向const对象的函数与形参指向non-const对象的函数能够构成重载。

// myFunc1能构成重载
int myFunc1(const int *a){}
int myFunc1(int *a){}
// myFunc2不能构成重载。形参本身是否为const对实参没有影响
int myFunc2(int *const a){}
int myFunc2(int *a){}
        另外,类的const成员函数与non-const成员函数也能构成重载。
// 构成重载
int MyClass::myFunc() //this指针类型为MyClass * const
{...}
int MyClass::myFunc() const // this指针类型为const MyClass * const
{...}

一般,成员函数修饰符如static, virtual等都只需要在类定义中成员函数声明处使用这些关键字,但const是个例外,必须同时在类定义中的成员函数声明处和类定义外部的成员函数定义处使用关键字const。理由就是上面所说,const成员函数与non-const成员函数构成重载,不是一个函数。


//xk> 构造函数不能为const

        构造函数不能声明为const。const构造函数是不必要的,即使创建一个const对象,因为构造函数的工作是初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值