const 作用在指针变量上, 有作用于指的针指向不能修改和作用于指针指向的变量不能修改的区别。
如果关键字 const 出现在星号左边, 表示被指向的对象是常量; 如果 const 出现在星号右边, 表示指针本身是常量, 不能指向其他内存空间; 如果 const 出现在星号两边表示指向的对象和指针本身都是常量。
int a = 0;
int b = 1;
const int* c = &a;
int* const d = &a;
*c = 2; //语法错误
c = &b;
*d = 2;
d = &b; //语法错误
const写在类型之前与const写在类型之后、 星号之后这两种写法的意义相同。
即下面两种写法是一样的:
void func(const QWidget* pw);//这两种写法是一样的
void func(QWidget const* pw);//
关于 STL 中的迭代器:
对普通的迭代器用 const 来修饰, 就像对指针以 const 修饰一样, 表示迭代器不再指向其他对象。 但迭代器当前指向的对象是可以改变的:
std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin();
*iter = 10;//正确
++iter; //错误, 迭代器不能再指向其他对象
如果要得到一个迭代器, 指向的对象不能通过迭代器改变, 则使用 const_iterator:
std::vector<int> vec;
std::vector<int>::const_iterator cIter = vec.begin();
*cIter = 10; //错误, 此处迭代器指向的对象不能通过此迭代器改变
++cIter; //正确
const 与 non-const 成员函数之间的复用
如果业务逻辑上一致, 工程上严谨的做法要求 non-const 成员函数 复用 const 成员函数。 因为 non-const 成员函数可能修改了当前对象的数据成员。简单例子如下:
class B
{
public:
const int& getb() const { return const_cast<B&>(*this).getb(); }
int& getb()
{
b = 7;//可能存在修改成员变量的隐患
return b;
}
private:
int b = 9;//此处写法为 C++11 特性
};
//使用例子
const B oj;
oj.getb();
cout << oj.getb() << endl; // 这里的打印结果为 7, 于逻辑上 const 对象 oj是矛盾的。
正确写法应该是下面这样:
class A
{
public:
inline const int& geta()const { return a; }
inline int& geta()
{
return const_cast<int&>(static_cast<const A&>(*this).geta());
}
private:
int a = 0;
};