03:尽可能使用const
1:const对指针和常量的修饰
char greeting[]="Hello";
char* p=greeting; //non-const pointer, non-const data
cons七char* p=greeting; //non-const pointer, const data
char* coast p=greeting; //const pointer, non-const data
coast char* coast p=greeting; // const pointer, const data
2:const对迭代器的修饰
STL迭代器系以指针为根据塑模出来,所以迭代器的作用就像个T*指针
std::vector<int> vec;
...
const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const
*iter=10; //没问题,改变iter所指物
++iter;//错误! iter是
std::vector<int>::const_iterator cIter = vec.begin();//cIter的作用像个const T*
*cIter=10; //错误! *cIter是const
++cIter;//没问题,改变cItero
3:令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性。
operator*声明式:
class Rational{…};
const Rational operator* (const Rational& lhs, const Rational& rhs);
Rational a, b, c;
...
若返回对象不是const,则下面情况也成立:
(a*b)=c; //在a*b的成果上调用operator=
这也是为什么operator*返回一个const对象的原因。
4:const成员函数
1)两个成员函数如果只是常量性(constness)不同,可以被重载。
void print(const TextBlock& ctb) //此函数中ctb是const
{
std::cout<<ctb[0]; //调用const TextBlock::operator[]
...
}
2)请注意,non-const operator[]的返回类型是个reference to char,不是char。如果operar[]只是返回一个char,下面这样的句子就无法通过编译:
tb[0]=’x';
那是因为,如果函数的返回类型是个内置类型,那么改动函数返回值从来就不合法。
3)bitwise constness(又称physical constness )
bitwise const阵营的人相信,成员函数只有在不更改对象之任何成员变量(static除外)时才可以说是const。也就是说它不更改对象内的任何一个bit 。 但也会有不符合bitwise constness的情况,却能通过编译,如下:
class CTextBlock{
public:
char& operator[](std::size t position) const //bitwise const声明
{return pText[position];} //但其实不适当.
private:
char* pText;
};
const CTextBlock cctb("Hello"); //声明一个常量对象。
char* pc=&cctb[0]; //调用const operator []取得一个指针
//指向cctb的数据。
*pc='J'; //cctb现在有了"Jello"这样的内容。
4)logical constness
这一派拥护者主张,一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。 若要在const成员函数内改变某成员变量,需要将该变量声名前面加上mutable。
class CTextBlock {
public:
...
std::size t length()const;
private:
char* pText;
mutable std::size_t textLength; //这些成员变量可能总是
mutable bool lengthIsValid; //会被更改,即使在
}; //const成员函数内。
std::size_t CTextBlock::length() const
{
if(!lengthIsValid){
textLength=std::strlen(pText); //现在,可以这样
lengthIsValid=true; //也可以这样。
}
return textLength;
}
5:在const和non-const成员函数中避免重复
const和non-const成员函数有代码重复了的解决办法。 有如下例子:
class TextBlock {
public:
...
const char& operator[](std::size一position) const
{
... //边界检验(bounds checking)
... //志记数据访问((log access data)
... //检验数据完整性(verify data integrity )
return text[position];
}
char& operator[](std::size t position)
{
... //边界检验(bounds checking)
... //志记数据访问(log access data)
... //检验数据完整性((verify data integrity )
return text[position];
}
private:
std::string text;
};
解决方案如下;
class TextBlock {
public:
const char& operator[](std::sizese 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 [ ]
);
}
...
}
注意:可以non-const调用const,但不能const调用non-const。
总结: 1:将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。 2:编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性” (conceptualconstness)。 3:当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
.
|