05 - const关键字

const关键字

关键字const表示使某些内容保持不变,编译器通过将任何试图将其更改的行为标记为错误。此外,启动优化后,编译器可以利用这一点生成更好的代码。

const的用法

修饰类型

在C语言中,常用预处理器的#define机制声明一个符号名称。而在C++中,鼓励使用const 取代#define定义常量。使用const定义常量,让编译器保证代码不会改变这个值:

const int version {2};
const std::string name {"I am name"};
const double PI {3.14159};

const与指针

const和指针搭上关系,理解起来可能就有点困难,这里用一个例子来加深理解:

int* ip;			// line 1
ip = new int[10];	// line 2
ip[4] = 5;			// line 3

如果要阻止修改ip指向的值(第三行),可以这样做:

const int* ip;		// 无法修改*ip, 即ip指向的值
ip = new int[10];
ip[4] = 8;			// 无法编译

如果要阻止修改ip本身,可以这样做:

int* const ip {new int[10]};	// 无法修改ip,即ip本身
ip[4] = 8;			

要想读懂这么复杂的变量声明,得要领悟该要点:

  • const关键字作用于其直接左侧的内容

例如:

const int* const ip{ nullptr };
// 也可以这样写
int const* const ip{ nullptr }; 

第一个const作用于ip指向的int,说明你不能修改ip指向的值;第二个const作用于*,说明你不能修改ip指针本身。

例如:

int* const ip;

ip是一个指向intconst指针,即不能修改ip本身。

int const* ip;

ip是一个指向const int的指针,即不能修改ip指向的值。

利用const保护参数

C++中,也能将非const变量转换为const变量,这提供了一定程度的保护,防止其他代码修改变量:

void myFunc(const string* str) 
{
    *str = "ttt";	// 无法编译
}

const方法

const关键字也能将类方法标记为const,防止他们修改类的数据成员:

class myClass
{
    /* ... */
public:
	std::string getName() const;
    void setName(std::string name);
    /* ... */
}

这里还有一个 const-correctness 原则:将不改变对象任何数据成员的成员函数声明为const

参考资料

  • 飘零的落花 - 现代C++详解
  • C++20高级编程