Effective C++(尽量使用const)

指针

const位置

char greeting[] = "Hello";
char *p = greeting;
const char *p = greeting;
char * const p = greeting;
const char * const p = greeting;

const在 *
号左边,代表指针指向的对象是const的。如果在右边,代表这个指针是const的。

相同const

void f1(const Widget *pw); // f1 takes a pointer to a constant Widget object
void f2(Widget const *pw); // so does f2

STL 迭代器const

std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin() ;//指针本身是const的
*iter = 10; // Right
++iter; // Error
std::vector<int>::const_iterator cIter = vec.begin( );  //指针指向的对象是const的
*cIter = 10; // Error
++cIter; // Right

函数与const

返回值const

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

返回值为const的原因

  1. if 错用
if (a * b = c) ...
  1. 书写错误
Rational a, b, c;
(a * b) = c;

参数const

同函数内部的local const一样。

const成员函数

  1. 得知那个函数可以改动对象内容
  2. 如果两个成员函数常量性不同,则他们可以重载。
class TextBlock {
public:
    const char& operator[](std::size_t position) const
    {
        return text[position];
    }
    char& operator[](std::size_t position)
    {
        return text[position];
    }
private:
    std::string text;
};

TextBlock tb("Hello");
std::cout << tb[0]; // call non-const version

const TextBlock ctb("World");
std::cout << ctb[0]; // call const version

应用

void print(const TextBlock& ctb)
{
    std::cout << ctb[0]; // calls const TextBlock::operator[]
}

std::cout << tb[0];
tb[0] = ’x’;

std::cout << ctb[0];
ctb[0] = ’x’; // Error

bitwise constness vs logic constness

c++默认支持bitwise constness

缺点

class CTextBlock {
public:
    char& operator[](std::size_t position) const
    {
        return pText[position]; //虽然满足C++的bitwise constness,但是实际上外部是可以修改pText所指向的内容
    }
private:
    char *pText;
};

比如这样做

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

logic constness

一个函数可以修改某些类里面的变量,但是被外部用户感知到。

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); //不满足C++的bitwise constness
        lengthIsValid = true;            //不满足C++的bitwise constness
    }
    return textLength;
}

怎么办?

class CTextBlock {
public:
    std::size_t length() const;
private:
    char *pText;
    mutable std::size_t textLength; // mutable释放掉non-static对象的const属性
    mutable bool lengthIsValid;     // mutable释放掉non-static对象的const属性
};

std::size_t CTextBlock::length() const
{
    if (!lengthIsValid) {
        textLength = std::strlen(pText);
        lengthIsValid = true; 
    }
    return textLength;
}

如何代码复用

class TextBlock {
public:
    const char& operator[] (std::size_t position) const
    {
        return text[position];
    }

    char& operator[] (std::size_t position)
    {
        return const_cast<char &>(static_cast<const TextBlock>(*this)[position]);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值