effective C++读书笔记 条款三 尽可能使用const

const允许你指定一个语义约束,告诉编译器不改动某个对象

关于指针的const,如果const出现在*左边,表示被指物是常量,如果出现在*右边,则表示指针是常量,如果两边都有,则表示指针和被指物都是常量。


void f1(const int* a);  //f1获得一个指针,指向一个常量
void f2(int const * a);	//f2也是
void f3(int* const a);    //f3获得一个常量指针,即指针不可指向别处

STL的迭代器就是以指针为根据塑造出来的,声明迭代器为const就像声明指针为const一样,即,你可以修改迭代器指向的东西的值,但这个迭代器不可以指向不同
的东西。如果你希望迭代器所指的东西不可改动,则需要 const_iterator:


std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin();	//iter的作用像个 T* const	
*iter = 10;						//没问题,改变iter所指物的值			
++iter;							//错误! iter是const
std::vector<int>::const_iterator citer = vec.begin();	//citer的作用像个const T*
*citer =10;						//错误!*citer是const
++citer;						//没问题,改变citer

为函数返回值加上const


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

用以阻止这样的暴行


Rational a,b,c;
(a*b)=c;

尽管难以想象为什么会有人相对两个值的乘积赋值,但很多人无意识中可能这么做,以及一个打字错误  if(a*b=c) //其实想做一个比较动作,即  == 
加上const 就可以省下这些恼人的错误


####################################################################################################




const成员函数


const指出函数能做的操作,也使操作“const”对象成为可能,如条款二十所言,改善C++程序效率的一个根本办法是以 pass-by-reference-to-const方式传递对象,而此技术可行的前提是,我们有const函数可用来处理取得的const对象。
(注:在C++中,只有被声明为const的成员函数才能被一个const类对象调用。)
如果两个成员函数只是常量性不同,则他们是可以被重载的。考虑以下class


class TextBlock{
public:
	const char& operator[](std::size_t position) const  //operator[] for const
	{return text[position];}
	char& operator[](std::size_t position)			//operator[] for non-const
	{return text[position];}
private:
	std::string text;
}
TextBlock的operator[]s可以被这么使用:
TextBlock tb("Hello");
std::cout << tb[0];			//调用non-const operator[]
const TextBlock ctb("World");
std::cout << ctb[0];			//调用const operator[]

如下调用


tb[0]='x';	//没问题
ctb[0]='x';     //错误


上述错误起因于对一个“由const版的operator[]返回”的const char&实行赋值动作。
也注意,non-const版本返回的是char&,不是char,否则就是对返回的拷贝值进行赋值动作,显然不合法。


const成员函数不允许修改class对象的数据成员,除非在其数据成员声明前加上 mutable ,这样,及时在const成员函数中,这些数据成员也可以被修改。


对于const对象


const TexrtBlock cctb("Hello");
char *pc=&cctb[0];
*pc='J';

这其中当然不会有任何错误:你仅仅调用了const成员函数,取了其地址,但你还是改变了它的值。


关于const函数的重载,可以采用代码重用。


用non-const版本调用const版本,而不是反过来,否则,因为non-const可能对对象做出改动,而const承诺不改动对象,这样是危险的。


利用转型static_cast和const_cast
(注:const_cast用来将类型的const、volatile和__unaligned属性移除。static_cast则不具这样的功能)


class TextBlock{
public:
	const char& operator[](std::size_t position) const  //operator[] for const
	{return text[position];}
	char& operator[](std::size_t position)			//operator[] for non-const
	{
		return
			const_cast<char&>(
				static_cast<const TextBlock&>(*this)
					[position]
			);
	}
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值