Effective C++ 精读

Effective C++ Term 3 尽可能使用const

2019-04-22  本文已影响0人  vancymoon

区分const修饰的对象

const出现在星号左边:被指物是常量

const出现在星号右边:指针本身是常量

char[] greeting = "Hello";
char[] another_greeting = "world";
const char* p1 = greeting;  // *p1不可变,但p1可以指向其他内容
char* const p2 = greeting;  // p2不能再指向其他内容,但内容本身仍可以被修改

p1[0] = 'h';            // 非法
p1 = another_greeting;  // 合法
p2[0] = 'h';  //合法
p2 = another_greeting;  // 非法

const修饰STL迭代器

std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin();  // iter本身为const
std::vector<int>::const_iterator iter = vec.begin();  // iter指向内容为const

令函数返回值为const

降低客户犯错的几率

如:a * b = c的代码就是不合法的

const成员函数

const作为函数类型可以形成重载(注意与返回类型为const相区别)

class MyClass {
public:
    void func() {
        cout << "base func" << endl;
    }

    void func() const {
        cout << "base func const" << endl;
    }
};

Base base1;
base1.func();  // "base func" 非const函数被优先调用,在不存在普通函数的情况才会调用const函数

const Base base2;
base2.func();  // "base func const" 只能调用const函数

mutable:const的摆动场

如果将变量声明为mutable,则即便在const函数中,变量仍然可以被修改:

class MyClass {
public:
    void func() {
        cout << "base func" << endl;
    }

    void func() const {
        cout << "base func const" << endl;
        num1 = 100;  // 合法,因为num1被声明为mutable,可以打破const约束
        num2 = 99;   // 非法,函数类型为const
    }

private:
    mutable int num1;
    int num2;
};

const和non-const成员函数避免重复

如果const和non-const成员函数实现功能完全相同,它们的区别仅仅由函数类型或返回类型区别的话,则可以让non-const成员函数调用const成员函数,只需要加上常量转除或做一次转型动作,以避免代码重复。下面的例子仅作为说明,不代表真的会写出这样的代码

简化前的代码:

class MyClass {
public:
    int func() {
        return a;
    }

    const int func() const {
        return a;
    }
private:
    mutable int a = 10;
};

简化后的代码:

class MyClass {
public:
    int& func() {
        return const_cast<int&>(static_cast<const MyClass&>(*this).func());
    }

    const int& func() const {
        return a;
    }

private:
    mutable int a = 10;
};

简化代码中,const_cast<int&>是去除返回值的常量,static_cast<const MyClass&>(*this)是为了强制调用const版本的函数,从而避免递归调动普通函数func()本身

上一篇 下一篇

猜你喜欢

热点阅读