条項21:できるだけconstを使用する
あなたが間違ったことをする衝動を防ぐ「const」!!
まず罠があります
typedef pC char*
void f 1(pC const p)/逆のようで、はっきり覚えていません
希望するchar*const//ポインタ定数ではなく、const char*p//定数ポインタです.
例はこうですね.typedefトラップキーワードを検索できます.
関数インタフェースでは
同じように定数を指すポインタです
constで冒頭に述べたように、多くの間違いを防止します.例えば、
(a * b) = c;//a*bの結果に値を付ける
関数の申明は
const rational operator*(const rational& lhs, const rational& rhs);
constもそうだと思っていましたが、次の例では驚くかもしれません.constのリロード関数での運用
operator[]を再ロードし、異なるバージョンの異なる戻り値を与えることで、constと非const stringを異なる処理できます.
戻り値でタイプを参照することにも注意してください.そうしないとcs[0]='x'になり、結果としてローカル変数に値が割り当てられます.
次の章ではconst関数のメンバーデータに対する修正とmutableキーワードを意味とデータから区別し,あまり興味がなく,コードデバッグを書くつもりはないと述べた.
でも最后にconstの総括に対してとても学ぶ価値があって、最后に自分で総括します
constというキーワードは意味的には修正されず、定数値です.しかし、いくつかの文法上の手足はこの約束に反する可能性があります.例えばクラスを定義して定義しました
データA型変換関数であり、constに設定される.次に、このクラスのインスタンスを指すポインタをデータ型Aで定義します.それに対して
修正しました.次に、やはり意味的に言えば、外見から見ると修正できないものがありますが、内部では修正したり値をつけたりする必要があります.どうすればいいですか.
どうですか.mutableキーワードを使って、いろいろな文法から制約するしかありません.
constの修正にはこのような方法があります.
外部では、
内部:
クラスのメンバー関数の1つで、thisポインタは次のように宣言されています.
c * const this;//非constメンバー関数で
const c * const this;//constメンバー関数で
しかし、局所変数ポインタを初期化し、thisが指す同じオブジェクトを指すようにすることで間接的に実現することができる.そして、このローカルポインタであなたにアクセスできます.
変更したいメンバー:
まず罠があります
typedef pC char*
void f 1(pC const p)/逆のようで、はっきり覚えていません
希望するchar*const//ポインタ定数ではなく、const char*p//定数ポインタです.
例はこうですね.typedefトラップキーワードを検索できます.
関数インタフェースでは
class widget { ... };
void f1(const widget *pw); // f1
// widget
void f2(widget const *pw); // f1
同じように定数を指すポインタです
constで冒頭に述べたように、多くの間違いを防止します.例えば、
(a * b) = c;//a*bの結果に値を付ける
関数の申明は
const rational operator*(const rational& lhs, const rational& rhs);
constもそうだと思っていましたが、次の例では驚くかもしれません.constのリロード関数での運用
class string {
public:
...
// const operator[]
char& operator[](int position)
{ return data[position]; }
// const operator[]
const char& operator[](int position) const
{ return data[position]; }
private:
char *data;
};
string s1 = "hello";
cout << s1[0]; // const
// string::operator[]
const string s2 = "world";
cout << s2[0]; // const
// string::operator[], , s2 const,
// const
operator[]を再ロードし、異なるバージョンの異なる戻り値を与えることで、constと非const stringを異なる処理できます.
string s = "hello"; // const string
cout << s[0]; // ——
// const string
s[0] = 'x'; // ——
// const string
const string cs = "world"; // const string
cout << cs[0]; // ——
// const string
cs[0] = 'x'; // !——
// const string
戻り値でタイプを参照することにも注意してください.そうしないとcs[0]='x'になり、結果としてローカル変数に値が割り当てられます.
次の章ではconst関数のメンバーデータに対する修正とmutableキーワードを意味とデータから区別し,あまり興味がなく,コードデバッグを書くつもりはないと述べた.
でも最后にconstの総括に対してとても学ぶ価値があって、最后に自分で総括します
constというキーワードは意味的には修正されず、定数値です.しかし、いくつかの文法上の手足はこの約束に反する可能性があります.例えばクラスを定義して定義しました
データA型変換関数であり、constに設定される.次に、このクラスのインスタンスを指すポインタをデータ型Aで定義します.それに対して
修正しました.次に、やはり意味的に言えば、外見から見ると修正できないものがありますが、内部では修正したり値をつけたりする必要があります.どうすればいいですか.
どうですか.mutableキーワードを使って、いろいろな文法から制約するしかありません.
constの修正にはこのような方法があります.
外部では、
class string {
public:
// , data
// value
string(const char *value);
...
operator char *() const { return data;}
private:
char *data;
};
const string s = "hello"; //
char *nasty = s; // operator char*() const
*nasty = 'm'; // s.data[0]
cout << s; // "mello"
内部:
クラスのメンバー関数の1つで、thisポインタは次のように宣言されています.
c * const this;//非constメンバー関数で
const c * const this;//constメンバー関数で
しかし、局所変数ポインタを初期化し、thisが指す同じオブジェクトを指すようにすることで間接的に実現することができる.そして、このローカルポインタであなたにアクセスできます.
変更したいメンバー:
size_t string::length() const
{
// const
// this
string * const localthis =
const_cast<string * const>(this);
if (!lengthisvalid) {
localthis->datalength = strlen(data);
localthis->lengthisvalid = true;
}
return datalength;
}