[持续更新] 我有特别的C++技巧之const

Effective C++第三条款:尽可能使用const

简介:

关键字const多才多艺。你可以用它在classes外部修饰global或者namespace作用域中的常量,或者修饰文件、函数或区块作用域中被声明为static的对象。

1 基础用法:

1.1 修饰变量

如果关键字const出现在星号左边,表示被指物是常量,如果出现在星号右边,那么表示指针自身是常量,如果出现在星号两边,表示被指物和指针都是常量。

char greeting[] = "Hello";
char * p = greetig;    //non-const pointer, non-const data
const char * p = greetig;    //non-const pointer, const data
char * const p = greetig;    //const pointer, non-const data
const char * const p = greetig;    //const pointer, const data


1.2 STL迭代器


STL迭代器系以指针为根据塑模出来,所以迭代器的作用就像T*指针。

const std::vector<int>::iterator iter = vec.begin();
*iter = 10; //没问题,改变了iter所指物
++iter;//错误,iter是const
const std::vector<int>::const_iterator citer = vec.begin();
*citer = 10; //错误,cIter是const
++citer;//没问题,改变citer
需要注意的点:
class Solution
{
private:
	static int num = 5;//错误,因为类内static初始化变量必须为const
	static const int num2 = 5.0;//正确
	static const float num3 = 5.0;//错误,因为类内static初始化变量必须为int bool 或者char
	static const float num4;//正确,只声明,不定义
public:
	int get(){ return (int)num2; };
};

const float Solution::num4 = 5;//非int型const static 数据得在实现文件中定义

2 进阶用法:

2.1 修饰函数

const最具威力的用法是面对函数声明时的应用。在一个函数声明式内,const可以和函数返回值、各参数、函数自身(如果是成员函数)产生关联。

      令函数返回一个常量值,往往可以降低因代码书写错误等造成的意外,而又不至于放弃安全性和高效性。举个例子:

 

class Rational{...};//class Rational定义
const Rational operator *{const Rational & lhs, const Rational & rhs};
也许你对这个声明不免斜着眼睛说,为什么返回一个const对象?因为如果不这这么多,那么可能写出这样的代码:

Rational a,b ,c;
(a*b) = c;//在a*b的成果上调用operator=

或者这样:

if(a*c=c)//其实是想比较

2.2 tips

可能你也一样,冷漠了一个事实:两个成员函数如果只是常量性(constness)不同,就可以重载。

2.3 类中函数后面添加const的意思是:该函数不改变类中的成员,例如:

class CTextBlock {
public:
   ...
   char& operator[](int pos) const//不改变类中变量
    {return pText[pos]}
    char * pText;
};

2.4 mutable关键字

    有时候需要在const更改类中成员变量,又不想去掉const关键字,那么就可以使用mutable关键字。

class cTextBlock {
public:
    int length()const;
private:
    mutable int size;
}
2.5 转型(casting)

有的时候,const版本和非const版本的函数都需要实现,那么,两个函数内,基本操作相同,这样代码冗余较多,例子如下:

class Solution
{
private:
	char * pText;
public:
	const char & operator[] (int pos)const//const版本
	{
		//边界检测
		//记录日志
		//检验数据完整性
		return pText[pos];
	};
	char & operator[] (int pos)//[]操作符非const版本
	{
		//边界检测
		//记录日志
		//检验数据完整性
		return pText[pos];
	}
};

为了避免这种情况,可以通过如下方法:

class Solution
{
private:
	char * pText;
public:
	const char & operator[] (int pos)const//const版本
	{
		//边界检测
		//记录日志
		//检验数据完整性
		return pText[pos];
	};
	char & operator[] (int pos)//[]操作符非const版本
	{
		//使用static_cast将this转化成const
		//之后再把结果转化成非const
		return const_cast<char &>(
			static_cast<const Solution&>(*this)[pos]
			);
	}
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值