[Effective C++]条款03:尽可能使用const

本文探讨了C++中const关键字的多种用途,包括声明全局常量、函数参数、返回类型和成员函数。const成员函数允许对const对象进行操作,并提供了代码安全性和效率。当const和non-const成员函数实现相同,可以使用const成员函数避免代码重复。通过const_cast解除const限制,可以在non-const成员函数中调用const成员函数,以实现代码复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 将某些东西声明为 const 可帮助编译器侦测出错误用法。 const 可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体
  • 编译器强制实施 bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
  • 当 const 和 non- const 成员函数有着实质等价的实现时,令non- const 版本调用 const 版本可避免代码重复

关键字 const 多才多艺,你可以用它在 classes 外部修饰 global 或 namespace 作用域中的常量,或修饰文件、函数、或区块作用域( block scope)中被声明为 static 的对象。你也可以用它修饰 classes 内部的 static 和non- static 成员变量。面对指针,你也可以指出指针自身、指针所指物,或两者都(或都不)是 const。

const最具威力的用法是面对函数声明时的应用。在一个函数声明式内, const 可以和函数返回值、各参数、函数自身(如果是成员函数)产生关联。
令函数返回一个常量值,往往可以降低因使用者错误而造成的意外,而又不至于放弃安全性和高效性。举个例子

class Rational {...};
const Rational operator* (const Rational& lhs, const Rational& rhs);

Rational a, b, c;
(a * b) = c;	//在 a * b 的结果上调用 operator=,将 operator* 的返回值声明为 const 可以预防该动作

const 成员函数

将 const 实施于成员函数的目的,是为了确认该成员函数可作用于 const 对象身上

const 成员函数重要的两个理由:

  • 它们使 class 接口比较容易被理解。我们可以得知哪个函数可以改动对象内容而哪个函数不行
  • 它们使“操作 const 对象”成为可能

两个成员函数如果只是常量性不同,是可以被重载的

bitwise const 阵营的人相信,成员函数只有在不更改对象之任何成员变量(static外)时才可以说是 const。也就是说它不更改对象内的任何一个bit。这种观点的好处是能很容易找到违反点:编译器只需寻找成员变量的赋值动作即可。bitwise constness 正是C++对常量性(constness)的定义,因此 const 成员函数不可以更改对象内任何 non- static 成员变量。

利用 C++ 的一个关键字: mutable(可变的)。mutable 释放掉 non-static 成员变量的 bitwise constness 约束

在 const 和 non- const 成员函数中避免重复

class TextBlock {
public:
...
const char& operator[](std:: size t position) const
{
   ...		//边界检验
   ...		//数据访问
   ...		//检验数据完整性
   return text[position];
}

//代码重复
char& operator[](std::size_ t position)
{
   ...		//边界检验
   ...		//数据访问
   ...		//检验数据完整性
   return text[position];
}
private:
    std::string text;
};

我们应该实现 operator[] 的功能一次并使用它两次。也就是说,令其中一个调用另一个。这促使我们将常量性转除(casting away constness)。

class TextBlock {
public:
...
const char& operator[](std:: size t position) const//一如既往
{
   ...		//边界检验
   ...		//数据访问
   ...		//检验数据完整性
   return text[position];
}

char& operator[](std::size_ t position)//现在只调用 const op
{
   return
     const cast<char&>(						  //将op[]返回值的 const 转除	
      static_cast<const TextBlock&>(*this)	 	//为*this加上 const
        [position]							 //调用 const op[]
     );
}
};

两次转型动作:

第一次:给 *this 添加 const,目的是明确指出调用的是 const operator[],防止 none-const operator[] 无限递归。

第二次:移除 const 属性。该动作只能由 const_cast 来完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值