C++:const
5467 ワード
const
const基本用法
1つのタイプのオブジェクトに対して
例:
なお、constオブジェクトの初期化は式で初期化されますが、私たちの例では定数式が使用されています.実際、const初期化は次の形式で行うことができます.
1つの特殊な状況は、この
constリファレンス
constリファレンスはconstオブジェクトへのリファレンスです.つまり、リファレンスの内容が
constリファレンスを一時オブジェクトにバインドするのは違法であることに注意してください.
コンパイルは可能ですが、これは意味のない参照バインドです.
constとポインタ
constはポインタを修飾することもできます.マルチレベルポインタの存在によりconstの結合も複雑になる.
最も一般的なのは定数ポインタと定数を指すポインタであり、前者はポインタが定数であることを示し、すなわち指向するアドレスは変更できないことを示し、後者は指向するアドレスに格納されている内容が定数であることを示す.定数ポインタと定数を指すポインタは
マルチレベルポインタに関連する場合、宣言式を右から左に読み、
constexpr式
前述したように、constオブジェクトは定数式または非常量式で初期化できます.定数式とは,コンパイル期間中に結果が得られる式であり,定数式から初期化されたconstオブジェクトが定数式の構成に関与してもよい.ある場合、1つの式がコンパイル期間中に決定されることを望んでいますが、複雑なプロジェクトで1つのオブジェクトが定数式であるかどうかを確認することは非常に困難であり、C++は
コンパイル期間中にconstexprオブジェクトの値を決定する必要があるため、ポインタと参照constexprの初期化にはより厳しい要求があります.一般的に、関数内に定義されたオブジェクトアドレスはコンパイル期間中に決定できないため、初期化定数式の値としては使用できません.逆に、グローバルオブジェクトは使用できます.
constと関数
constとクラス
constはクラスのメンバー関数を修飾することができ、修飾されたメンバー関数を常メンバー関数と呼び、常メンバー関数をすべてのオブジェクトで呼び出すことができますが、常オブジェクトは常メンバー関数のみを呼び出すことができます.これは、メンバー関数のパラメータリストには、
クラスのメンバーがconstオブジェクト内でも情報を記録することを望む場合があります.この場合、C++は
const
はC++が提供する強力なキーワードであり、const
の使い方は非常に多いが、総じて言えば、const
の役割は1つしかない:修飾された内容がプログラムによって修正されないことを保証する.const基本用法
1つのタイプのオブジェクトに対して
const
修飾を使用すると、すなわち、このオブジェクトが読み取り専用であり、修正操作ができないことが制限され、修正操作ができないため、const
オブジェクトを宣言する際に同時に値を付与または初期化する必要がある.constオブジェクトの初期化は一般的に次の形式です.const TypeName Var = Expression;
例:
const int a = 0;
int const a = 0; //
a = 1; //
なお、constオブジェクトの初期化は式で初期化されますが、私たちの例では定数式が使用されています.実際、const初期化は次の形式で行うことができます.
int getA() {
return 0;
}
const int a = 0; // 0 , ,a
const int b = getA(); // getA() ,b
1つの特殊な状況は、この
const
オブジェクトがグローバル役割ドメインに存在することを望む場合、宣言時にextern
修飾を加えることができ、宣言時に初期値を付与しないことができるが、プログラムが少なくとも1つの宣言初期値を有することを保証しなければならない.// A.cpp
extern const int a;
// B.cpp
extern const int a = 0;
constリファレンス
constリファレンスはconstオブジェクトへのリファレンスです.つまり、リファレンスの内容が
const
オブジェクトであるかどうかに関係なく、リファレンスの内容が変更されないことを確認します.int a = 0;
const int b = 0;
const int &c = a; // , a , c a
const int &d = b; // ,b、d
constリファレンスを一時オブジェクトにバインドするのは違法であることに注意してください.
int a = 0;
const int &b = a + 1; // a+1
//
const int temp1 = a + 1;
const int &b = temp1;
const double &c = a; //
//
const double temp = a;
const double &c = temp;
コンパイルは可能ですが、これは意味のない参照バインドです.
constとポインタ
constはポインタを修飾することもできます.マルチレベルポインタの存在によりconstの結合も複雑になる.
int a = 0;
const int b = 0;
const int *c = &a; // ,c , a
//
int const *c = &a;
const int *d = &b; // ,b ,c
int *e = &b; // ,b ,
const int *f = &b; // ,b ,f
最も一般的なのは定数ポインタと定数を指すポインタであり、前者はポインタが定数であることを示し、すなわち指向するアドレスは変更できないことを示し、後者は指向するアドレスに格納されている内容が定数であることを示す.定数ポインタと定数を指すポインタは
const
で修飾された1級ポインタの2つの場合で、『C++Primer』という本では、両者をそれぞれ最上位constと最上位constと呼ぶ.const int a = 0;
const int *b = &a; // b , const
int c = 0;
int * const d = &c; // d , const
const int * const e = &a; // e
マルチレベルポインタに関連する場合、宣言式を右から左に読み、
const
がどのレベルを修飾しているかを確認することができます.int a = 0;
int *b = &a; // b
int **c = &b; // c
int **const *d = &c; // d
/*
:
1. d
2. *, d ,
3. const,
4. *,
5. *,
6. int, int
*/
d = &c; // ,d
*d = &b; // , d
**d = &a; // , d
constexpr式
前述したように、constオブジェクトは定数式または非常量式で初期化できます.定数式とは,コンパイル期間中に結果が得られる式であり,定数式から初期化されたconstオブジェクトが定数式の構成に関与してもよい.ある場合、1つの式がコンパイル期間中に決定されることを望んでいますが、複雑なプロジェクトで1つのオブジェクトが定数式であるかどうかを確認することは非常に困難であり、C++は
constexpr
キーワードを導入し、あるオブジェクトが定数式であることを明示的に説明します.constexpr int a = 0; // , 0
constexpr int b = getB(); // getB()
コンパイル期間中にconstexprオブジェクトの値を決定する必要があるため、ポインタと参照constexprの初期化にはより厳しい要求があります.一般的に、関数内に定義されたオブジェクトアドレスはコンパイル期間中に決定できないため、初期化定数式の値としては使用できません.逆に、グローバルオブジェクトは使用できます.
constと関数
const
は、関数のパラメータを修飾することができる.int LiF(const int lif);
// , lif
// , ,
int LiF(const int *lif);
// ,
int LiF(const int &lif);
// , ,
const
はまた、関数の戻り値を修飾することもできる.const
は、関数の戻り値が変更されないこと、すなわち左の値として使用できないことを保証する.const int& LiF(int &lif) {
return lif;
}
constとクラス
const
はクラスのメンバーを修飾することができ、コンストラクション関数を呼び出すとオブジェクトの内容が確認されるため、すなわちconstメンバーはコンストラクション関数の前に初期化する必要があり、修飾されたクラスメンバーは初期化リストでのみ初期化される.class LiF {
public:
LiF(int _lif): lif(_lif) {}
private:
const int lif;
};
constはクラスのメンバー関数を修飾することができ、修飾されたメンバー関数を常メンバー関数と呼び、常メンバー関数をすべてのオブジェクトで呼び出すことができますが、常オブジェクトは常メンバー関数のみを呼び出すことができます.これは、メンバー関数のパラメータリストには、
this
ポインタが暗黙的に渡され、const
でメンバー関数が修飾され、実際にはthis
が修飾され、const *
は通常のポインタタイプに変換できないため、通常のメンバー関数を呼び出すことができないためである.また、関数リロードは下位constを無視しないため、メンバー関数のconst
に基づいてリロードを構成してもよい.非常に正確な一致によって通常のメンバー関数が見つかり、通常のオブジェクトは対応する通常のメンバー関数に一致します.class LiF {
public:
int get() { return lif; }
int get() const { return lif; } //
private:
int lif;
};
LiF l1;
const LiF l2;
l1.get(); // int get();
l2.get(); // int get() const;
クラスのメンバーがconstオブジェクト内でも情報を記録することを望む場合があります.この場合、C++は
mutable
キーワードを提供する永遠に可変なメンバーが必要である.class LiF {
public:
void count() const {
lif++;
}
private:
mutable int lif;
};
LiF l1;
const LiF l2 = l1;
l2.count();
const
はまた、メンバー関数の戻り値を修飾し、通常の関数のconst戻り値と同様にチェーン呼び出しを禁止したり、戻り値が左になったりすることを禁止することもできる.class LiF {
public:
const LiF& operator= (const LiF &l) {
lif = l.lif;
return *this;
}
const LiF& set(int _lif) {
lif = _lif;
return *this;
}
private:
int lif;
};
LiF l1, l2, l3;
l1 = l2 = l3; //
(l1 = l2) = l3; // , ,
LiF l4;
l4.set(1); //
l4.set(1).set(2); // ,set(1) this