条款3:尽可能使用const
1 bitwise const
成员函数如果是const意味着什么?有个所谓的bitwise const 的说法。即编译器认为,const成员函数不可以更改对象内任何non-static成员变量。
但是一个更改了“指针所指物”的成员函数虽然不能算const,但如果只有指针(而非其所指物)隶属于对象,那么称此函数为bitwise const 不会引起编译器异议。
说人话就是,理论上 const成员函数 表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。
但是bitwise constness机制产生的漏洞可以使我们改变成员
通过获得静态成员对象的指针,并修改指针内容做到。
下面会有示例代码。不急,我们接着往下讲其他内容。
2 logical constness
一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。
利用C++的一个与const相关的摆动场:mutable(可变的),
mutable释放掉non-static成员变量的bitwise constness约束。
也就是说成员变量加上mutable关键字就能使其在const成员函数内被修改
ok上代码 慢慢理解吧
#include <iostream>
#include<string>
using namespace std;
class CTextBlock
{
public:
//常量一定要初始化,在这里叫初始化,虽然效果和赋值一样
//,但是速度更快
CTextBlock(const std::string& str):text_const(1)
{
//a=1; 赋值
this->pText = (char*)str.c_str();
}
/*
CTextBlock(const char* c)
{
//我曾经试了其他的初始化静态字符串的方法,
//但是并不能触发bitwise constness漏洞机制
//我试图去理解,后面发现是因为c_str的特殊机制
//c_str是一个临时指针指向string。具体详情去自行百度
this->pText = (char*)(c);
this->pText = const_cast<char*>(c);
std::cout << pText<<std::endl;
}
*/
~CTextBlock()
{
}
friend std::ostream& operator << (std::ostream & os, const CTextBlock &p);
//bitwise const 声明
char& operator[](std::size_t position)const
{
return pText[position];//其实不恰当
}
void print()const
{
std::cout << this->pText << std::endl;
}
size_t lenth() const
{
if (!lenthIsValid)
{
textLenth = strlen(pText);
lenthIsValid = true;
}
return textLenth;
}
private:
char* pText;
const int text_const;
mutable size_t textLenth;
mutable bool lenthIsValid;
};
std::ostream& operator<<(std::ostream & os,const CTextBlock &p){
os << p.pText;
return os;
}
int main()
{
//测试bitwise constness漏洞机制
const CTextBlock cctb("Hello");//声明一个常量对象
std::cout << cctb << endl;//Hello
char* pc = &cctb[0];//调用const operator[] 取得一个指针
//指向cctb数据
*pc = 'j'; //cctb现在有了jello这样的内容
std::cout << cctb << endl;//jello
// 测试logical constness
std::cout << cctb.lenth();
return 0;
}
运行结果: