《Effective C++》学习笔记 03

本文详细介绍了const在C++中的应用,包括const对指针和常量的修饰、对迭代器的影响、const成员函数的使用,以及如何避免const和non-const成员函数的代码重复。强调了const在确保编译器检测错误、维持逻辑常量性以及优化代码方面的重要性。
摘要由CSDN通过智能技术生成

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版本可避免代码重复

.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值