栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【Effective C++】item03: Use const whenever possible.

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Effective C++】item03: Use const whenever possible.

尽可能使用const

const多才多艺。可以修饰全局、局部变量,或修饰文件、函数或者区块作用域中被声明为static的对象。也可以用来修饰class内部的static和non-static成员变量。

const修饰指针

对于指针,const可以修饰指针所指物,也可以修饰指针本身。

char greeting[] = "Hello";
char* p = greeting; // non-const pointer, non-const data
const char* p1 = greeting; // non-const pointer, conda data
char* const p2 = greeting; // const pointer, non-const data
const char* const p3 = greeting; // const pointer, const data

记忆方法,当const出现在 * 左侧的时候,表示被指物是常量;当const出现在 * 右侧时,表示的是指针自身是常量。

const修饰函数
  1. 修饰返回值
class Rational
{
private:
    
public:
    Rational() {}
    ~Rational() {}
    friend const Rational operator* (const Rational& lhs, const Rational& rhs);
};

虽然不建议返回const对象,但是有时会避免一种不经意间发生的错误。

Rational a, b, c;
if (a * b = c) { // error: passing 'const Rational' as 'this' argument discards qualifiers
    // todo
}
  1. const成员函数
class Fred {
public:
  void inspect() const;   // This member promises NOT to change *this
  void mutate();          // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
  changeable.inspect();   // Okay: doesn't change a changeable object
  changeable.mutate();    // Okay: changes a changeable object
  unchangeable.inspect(); // Okay: doesn't change an unchangeable object
  unchangeable.mutate();  // ERROR: attempt to change unchangeable object
}
  1. const-overloading
class Fred {  };
class MyFredList {
public:
  const Fred& operator[] (unsigned index) const;  // Subscript operators often come in pairs
  Fred&       operator[] (unsigned index);        // Subscript operators often come in pairs
  // ...
};
很多人忽视了一个C++的重要特性:两个成员函数如果只是常量性(constness)不同,可以被重载。

通常下标运算符重载成对出现。

```cpp
void f(MyFredList& a)  // The MyFredList is non-const
{
  // Okay to call methods that inspect (look but not mutate/change) the Fred at a[3]:
  Fred x = a[3];       // Doesn't change to the Fred at a[3]: merely makes a copy of that Fred
  a[3].inspect();      // Doesn't change to the Fred at a[3]: inspect() const is an inspector-method
  // Okay to call methods that DO change the Fred at a[3]:
  Fred y;
  a[3] = y;            // Changes the Fred at a[3]
  a[3].mutate();       // Changes the Fred at a[3]: mutate() is a mutator-method
}
void f(const MyFredList& a)  // The MyFredList is const
{
  // Okay to call methods that DON'T change the Fred at a[3]:
  Fred x = a[3];
  a[3].inspect();
  // Compile-time error (fortunately!) if you try to mutate/change the Fred at a[3]:
  Fred y;
  a[3] = y;       // Fortunately(!) the compiler catches this error at compile-time
  a[3].mutate();  // Fortunately(!) the compiler catches this error at compile-time
}
  1. 物理常量 vs 逻辑常量
    物理常量(physical constness)也称为bitwise constness。物理常量的阵营认为,成员函数不更改对象内的任意一个bit。

而不幸的是,很多成员函数并不十足具备const的性质却能通过bitwise的测试。
比如如下代码,我们有一个类型为char*的成员变量,operator[]不更改pText,于是编译器开心地认为它是bitwise的。

但是,事实上通过以下代码,终究改变了其值。

class TextBlock
{
private:
    
    char* pText;
    mutable std::size_t textLength;
    // std::size_t textLength;
    mutable bool lengthIsValid;
    // bool lengthIsValid;
public:
    TextBlock() {}
    ~TextBlock() {}
    std::size_t length() const;
    char& operator[](std::size_t position) const { // bitwise声明,但是不适当。
        return pText[position];
    }
};
std::size_t TextBlock::length() const
{
    if (!lengthIsValid) {
        textLength = std::strlen(pText);
        lengthIsValid = true;
    }
    return textLength;
}
const TextBlock tb("abcd");
char* pc = & tb[0];
*pc = 'T';
Reference
  • IOS CPP: Const Correctness
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1008659.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号