条款3:尽可能使用const

条款3:尽可能使用const

1、const 常量

const char* channel_no = "01";   //指向常量的指针,可重新修改指向对象地址,但不能修改指向值
char* const channel_info = "info"; //常量指针,指针本身是常量,可重新修改指向内容,但不能修改指向对象
const char* const channel_type = "APN"; //指向常量的常量指针,上面两种结合</span>

const迭代器
声明为const的迭代器跟声明为常量指针一样,表明该迭代器不能重新指向其他地址,但可以修改指向的值。
std::vector<int> vec;
const std::vector<int>::iterator v_itor = vec.begin();
*v_itor = 20;   //ok
v_itor++;  //wrong</span>
可以使用const_itorator解决,与指向常量指针一样,如上。
std::vector<int>::const_iterator cv_itor = vec.begin();
*cv_itor = 20;  //wrong
cv_itor++; //ok</span>

2、const与函数

const可以修饰函数返回值,函数参数,函数本身。

2、1函数返回const值

定义一个复数类
class Complex
{
public:
	Complex(int x, int y) : m_x(x), m_y(y)
	{

	}

	const Complex operator + (const Complex &rhs)
	{
		return Complex(this->m_x + rhs.m_x, this->m_y + rhs.m_y);
	}

private:
	int m_x;
	int m_y;
};</span>
测试
        Complex CA(2, 3);
	Complex CB(4, 5);
	Complex C = CA + CB;

	if (CA + CB = C)   //error C2678: 二进制“=”: 没有找到接受“const Complex”类型的左操作数的运算符(或没有可接受的转换)
	{
		//do something
	}</span>

将函数返回值定义为const可以预防程序员一些不可思议的赋值。

2、2、const参数

    在声明函数时,如果该参数作为一个输入参数,则尽可能的定义为const参数,不仅可以保护传入参数,后续会讲到类时const加上引用给程序提高很大效率。

2、3 const成员函数

①调用方法规则
关于常量对象和常量成员函数的使用方法如下:

(1)非常量对象调用非常量成员函数         (正确)

(2)非常量对象调用常量成员函数           (正确)

(3)常量对象调用常量成员函数             (正确)

(4)常量对象调用非常量成员函数           (错误)

关于成员函数和常量成员函数的使用方法如下:

(1)非常量成员函数调用常量成员,不能修改常量         (正确)

(2)非常量成员函数调用常量成员函数                  (正确)

(3)常量成员函数调用非常量成员函数                  (错误)

(4)常量成员函数调用常量成员变量                    (正确)

(5)常量成员函数调用非常量成员变量,不能进行赋值操作(正确)

②实现函数重载

在Complex类中加入一个const Complex operator + (const Complex &rhs) const函数

<1>	const Complex operator + (const Complex &rhs) const
	{
		return Complex(this->m_x + rhs.m_x, this->m_y + rhs.m_y);
	}

<2>	const Complex operator + (const Complex &rhs) 
	{
		return Complex(this->m_x + rhs.m_x, this->m_y + rhs.m_y);
	}</span>
测试

	const Complex CA(2, 3);
	Complex CB(4, 5);
	Complex C = CA + CB;   //call <1>
	Complex D = CB + CA;   //call <2></span>

③可以使用non-const版本调用const版本

下面是书上的例子,表明bit constness(位不变)的观点,即在const函数中不能进行对成员赋值操作

class CTextBlock {  
public:  
   
std::size_t length() const;  
private:  
char* pText;  
std::size_t textLength; //最近一次计算的文本区块长度。  
bool lengthIsValid; //目前的长度是否有效。  
};  
std::size_t CTextBlock::length() const  
{  
if(!lengthIsValid) {  
textLength = std::strlen(pText); //错误!在const成员函数内不能赋值给textLength和lengthIsValid。  
lengthIsValid = true;  
}  
return textLength;  
}  

另一方的观点代码就不贴出来了,使用mutable(可变的)关键字,mutable释放掉non-static成员变量的bitwise constness约束。


存在一些情况,const成员函数与non-const成员函数功能一样,为了避免代码重复,可以通过下面方式non-const函数调用const函数。

const char& operator[](size_t position) const //operator[] for const 对象  
{  
	.....  //do
	.....  //do
	.....  //do
	return text[position];  
}  
char& operator[](size_t position) //operator[] for non-const 对象  
{
	return  const_cast<char &> (static_cast<const TextBlock  &> (*this)[position]);
} 

第二个返回值解析:先将该对象转换为常量对象,调用cosnt operator[]函数,最后去掉常量熟悉

记住:

1.将某些东西声明为const可帮助编译器侦测出错误用法.const可被施加于任何作用域的对象,函数参数,函数返回类型,成员函数本体.

2.编译器强制实施bitwise constness,但你编写程序时应该使用"概念上的常量性"(conceptual constness);

3.当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值