[解決済み] C++で "const "はいくつあり、どのように使われるのですか?
質問
C++の初心者プログラマである私にとって、まだ非常に不明瞭に見える構成要素がいくつかあります。
const
. これは、非常に多くの場所で使用することができ、非常に多くの異なる効果を持つので、初心者が生きて出てくることはほとんど不可能です。C++の第一人者が、様々な使い方と、それを使うべきか使わないべきかを永遠に説明してくれないでしょうか?
どのように解決するのですか?
いくつかの用途を収集しようとしています。
reference-to-constにいくつかの一時的なものをバインドし、その寿命を長くする。 参照は基底であることができます - そしてそれのデストラクタは仮想である必要はありません - 正しいデストラクタがまだ呼び出されます。
ScopeGuard const& guard = MakeGuard(&cleanUpFunction);
説明 を、コードを使って説明します。
struct ScopeGuard {
~ScopeGuard() { } // not virtual
};
template<typename T> struct Derived : ScopeGuard {
T t;
Derived(T t):t(t) { }
~Derived() {
t(); // call function
}
};
template<typename T> Derived<T> MakeGuard(T t) { return Derived<T>(t); }
このトリックは Alexandrescu の ScopeGuard ユーティリティクラスで使用されています。一旦テンポラリがスコープ外に出ると、Derived のデストラクタが正しく呼び出されます。上記のコードはいくつかの小さなディテールを見逃していますが、それがこのコードの大きな特徴です。
メソッドがこのオブジェクトの論理的な状態を変更しないことを伝えるためにconstを使用します。
struct SmartPtr {
int getCopies() const { return mCopiesMade; }
};
コピーオンライトのクラスにはconstを使用する コピーする必要があるときとないときの判断をコンパイラが手助けしてくれるようにするためです。
struct MyString {
char * getData() { /* copy: caller might write */ return mData; }
char const* getData() const { return mData; }
};
説明 : 何かをコピーするとき、元のオブジェクトとコピーされたオブジェクトのデータが同じである限り、データを共有したいと思うかもしれません。しかし、どちらかのオブジェクトのデータが変更されると、今度は2つのバージョンが必要になります。1つはオリジナル、もう1つはコピーです。つまり、あなたは コピー の上に を書く を実行することで、両方のオブジェクトがそれぞれのバージョンを持つようになります。
コードの使用 :
int main() {
string const a = "1234";
string const b = a;
// outputs the same address for COW strings
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
上のスニペットは、私のGCCでは同じアドレスを表示します。これは、使用するC++ライブラリがコピーオンライトを実装しているからです。
std::string
. 両方の文字列は、別々のオブジェクトであるにもかかわらず、文字列データのために同じメモリを共有しています。作成方法
b
を非恒等式にすると、非恒等式バージョンの
operator[]
のデータに影響を及ぼしてはならないので、GCCはバッキングメモリバッファのコピーを作成します。
a
!
int main() {
string const a = "1234";
string b = a;
// outputs different addresses!
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
copy-constructorがconstオブジェクトとtemporaryからコピーを作成するためのものです。 :
struct MyClass {
MyClass(MyClass const& that) { /* make copy of that */ }
};
自明な変更不可能な定数を作るために
double const PI = 3.1415;
任意のオブジェクトを値ではなく、参照で渡すために - 高価な、あるいは不可能な値による受け渡しを防ぐために
void PrintIt(Object const& obj) {
// ...
}
関連
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] C++のファンクターとその使い方とは?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】'std::cout'への未定義の参照