天天看點

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

1. const與指針、疊代器

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結
effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結
effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

2. const成員函數

2.1 const與non-const重載

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結
effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結
#include <iostream>
#include <string>
using namespace std;

class CTextBook
{
public:
  CTextBook(string s) : text(s) {};
  ~CTextBook() {};
  const char& operator[](size_t position) const{ //operator for const object
    cout << "const operator[] called" << endl;
    return text[position];
  }
  char& operator[](size_t position){  //operator for non-const object
   cout << "non-const operator[] called" << endl;
    return text[position]; 
  }
private:
  string text;
};

int main()
{
  CTextBook nc("non-const");
  const CTextBook c("const");
  cout << nc[0] << endl;
  cout << c[0] << endl;
  return 0;
}
           

輸出:

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

2.2 bitwise constness

bitwise const

陣營的人認為,成員函數隻有在不改變對象的任何成員變量時(

static

除外)才可以說是

const

。…

bitwise constness

正是C++對常量的定義,是以在

const

成員函數中不能更改對象内的任何

non-const

成員變量。 如果成員變量聲明前有

mutable

則可以在

const

成員函數中被改變。

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

有些函數雖然寫明了是const,但是函數内有對指針(某一成員變量)的操作,不會引發編譯錯誤。

這個比較難了解。

#include <iostream>
#include <string>
using namespace std;

class CTextBook
{
public:
  CTextBook(string s){
    text = const_cast<char*>(s.c_str());
  };
  ~CTextBook() {
  };
  char& operator[](size_t position) const {//在const成員函數中确實沒有改變其他成員變量
    return text[position]; 
  }
private:
  char* text;
};

int main()
{
  const CTextBook c("const");
  cout << c[0] << endl;
  c[0] = 'x';// c是const的, 但是其中的值可以改變, 這不符合邏輯, 實際上是因為const成員函數的傳回值不是const的
  cout << c[0] << endl;
  return 0;
}
           

輸出:

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

在const成員函數中不能改變成員變量,除非成員變量前加上mutable。否則會編譯出錯!

2.3 在const與non-const成員函數中避免重複

如果想在const成員函數中修改其他成員變量,需要在其他成員變量前加上mutable,但是總感覺怪怪的。

避免重複的方法就是在non-const函數中調用const成員函數,并且轉型(casting)。

#include <iostream>
#include <string>
using namespace std;

class CTextBook
{
public:
  CTextBook(string s){
    text = const_cast<char*>(s.c_str());
  };
  ~CTextBook() {
  };
  
  const char& operator[](size_t position) const {
    cout << "const operator[] called" << endl;
    return text[position];
  }

  //在non-const成員函數中調用const成員函數, 這樣non-const與const類型的對象都能調用相關的函數.而且代碼得到複用
  char& operator[](size_t position){
    cout << "non-const operator[] called" << endl;
    return const_cast<char&>(static_cast<const CTextBook&>(*this)[position]);
  }
private:
  char* text;
};

int main()
{
  CTextBook nc("non-const");
  const CTextBook c("const");
  cout << nc[0] << endl;
  cout << c[0] << endl;
  return 0;
}
           

輸出:

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

可以看出,

cout << nc[0] << endl;

這句調用的是

non-const

成員函數,但是

non-const

成員函數中又調用了

const

成員函數,是以先輸出·non-const operator[] called·再輸出

const operator[] called

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

const成員函數承諾不改變對象的邏輯狀态,但是non-const不承諾,是以在const成員函數中不能調用non-const成員函數,反之則可以。

2.4 const對象預設調用const函數,non-const對象預設調用non-const函數

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

如果const函數與non-const函數同時存在,則const對象預設調用const函數,non-const對象預設調用non-const函數。

3.總結

effective c++:條款03:盡可能使用const1. const與指針、疊代器2. const成員函數3.總結

注意第三條!

繼續閱讀