問題タブ [explicit-constructor]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - メソッド/コンストラクターを明示的に指定すると、暗黙的に呼び出すことができないということですか?
メソッド/コンストラクターを明示的に指定すると、暗黙的に呼び出すことができないということですか? つまり、コンストラクターが明示的に指定されている場合、= のような演算子やコンバーターコンストラクターのような他のメソッドによって暗黙的に呼び出すことはできませんか?
その場合、メソッド/コンストラクターを明示的に指定することはまったく重要ですか?メソッド/コンストラクターを明示的に指定する利点は何ですか?
c++ - デフォルトのコンストラクターと、2 つ以上の (デフォルト以外の) パラメーターを持つコンストラクターで明示的に許可されるのはなぜですか?
1 つの (デフォルトではない) パラメーターを持つコンストラクターは、そのパラメーターの型からクラスの型に変換する暗黙的なコンバーターのように機能することを理解しています。ただし、explicit
任意のコンストラクター、パラメーターを持たないコンストラクター (既定のコンストラクター)、または 2 つ以上のパラメーターを持つコンストラクター (既定以外のコンストラクター) を修飾するために使用できます。
これらのコンストラクターで明示的に許可されているのはなぜですか? これが何らかの暗黙の変換を防ぐのに役立つ例はありますか?
c++ - C++ コピー初期化と直接初期化、奇妙なケース
これを読み続ける前に、コピー初期化と直接初期化の間に C++ に違いはありますか?を読んでください。まず、それが何について話しているのかを理解していることを確認してください。
最初にここでルールを要約します (標準 n3225 8.5/16、13.3.1.3、13.3.1.4、および 13.3.1.5 を読んでください)。
1) 直接初期化の場合、すべてのコンストラクターはオーバーロード セットと見なされ、オーバーロード解決はオーバーロード解決ルールに従って最適なものを選択します。
2) コピーの初期化の場合、コピー元の型がコピー先の型と同じか、コピー先の型から派生したものである場合、ルールは上記と同じですが、変換するコンストラクター (明示的なコンストラクターがないコンストラクター) のみがオーバーロード セットと見なされる点が異なります。これは実際には、明示的なコピー/移動コンストラクターがオーバーロード セットと見なされないことを意味します。
3) 上記 (2) に含まれないコピーの初期化のケース (ソースの型が宛先の型とは異なり、宛先の型から派生していない) については、まず、ソースの型から宛先の型に変換できるユーザー定義の変換シーケンスを検討するか、または (変換関数を使用する場合) をその派生クラスに変換します。変換が成功した場合、結果は宛先オブジェクトを直接初期化するために使用されます。
3.1) このユーザー定義の変換シーケンスでは、8.5/16 および 13.3.1.4 の規則に従って、変換する ctor (非明示的な ctor) と非明示的な変換関数の両方が考慮されます。
3.2) 結果の prvalue は、(1) に記載されている規則に従って、宛先オブジェクトを直接初期化します。8.5 /16 を参照してください。
さて、ルールについては十分です。いくつかの奇妙なコードを見てみましょう。私の推論がどこで間違っているのか、または単にすべてのコンパイラが間違っているのか、まったくわかりません。助けてください、ありがとう。
私の理解では、(1)については、
C++ には関数 return をコピー初期化と見なす規則があるため、上記の規則に従って、2 は最初に暗黙的に A に変換されますが、A にはコンストラクタ A(int) があるため、これは問題ないはずです。次に、変換された一時的な prvalue を使用して、返されたオブジェクトを直接初期化します。直接初期化では明示的なコピー コンストラクターを使用できるため、これも問題ありません。したがって、GCCは間違っています。
(2)については、
私の理解では、最初に b は演算子 A() によって暗黙的に A に変換され、次に変換された値を使用して a を直接初期化します。これはもちろん明示的なコピー コンストラクターを呼び出すことができますか? したがって、これはコンパイルに合格するはずで、すべてのコンパイラが間違っていますか?
(2) の場合、Visual C++ と clang の両方に「エラー、B から A に変換できません」のようなエラーがありますが、A のコピー コンストラクターで明示的なキーワードを削除すると、エラーはなくなります。
読んでくれてありがとう。
編集 1
誰かがまだ私の意図を理解していないので、8.5/16 から次の標準を引用します。
それ以外の場合 (つまり、残りのコピー初期化の場合)、ソース型から宛先型、または (変換関数が使用されている場合) その派生クラスに変換できるユーザー定義の変換シーケンスは、13.3 で説明されているように列挙されます。 1.4 であり、過負荷解決 (13.3) によって最適なものが選択されます。変換ができないか、あいまいな場合は、初期化の形式が正しくありません。選択された関数は、初期化式を引数として呼び出されます。関数がコンストラクターの場合、呼び出しは、目的の型の cv 修飾されていないバージョンの一時を初期化します。一時的なものは prvalue です。呼び出しの結果 (コンストラクターの場合は一時的なもの) は、上記の規則に従って、直接初期化するために使用されます。コピー初期化の宛先であるオブジェクト。場合によっては、中間結果を初期化されるオブジェクトに直接構築することにより、この直接初期化に固有のコピーを排除する実装が許可されます。12.2、12.8を参照。
ユーザー定義の変換後に直接初期化することについて言及していることに注意してください。つまり、私の理解では、次のコードは、私がコメントしたようにルールに従う必要があります。これは、clang、coomeau online、visual c++ の両方で確認されていますが、GCC 4.4.3 は (1) と (2) の両方で失敗します。これは奇妙なルールですが、標準からの推論に従います。
c++ - C++ 継承に関する質問
これについて質問があります:
最後の行がmain
コンパイルされる理由を教えてください。代わりにオブジェクトを期待するint
intoのコンストラクターを渡します。はinのコンストラクタに変換されていると思いますが、なぜですか?B
A
int
A
B
前もって感謝します。
アヴリ。
c++ - C++での配置の新しいVS明示的コンストラクター呼び出し
最近、メモリ内の特定の場所にオブジェクトを作成する2つの方法に出くわしました:
1。
2.2。
2番目の方法は少し短いです...他に違いはありますか?よろしくマテウス
c++ - すべてのC++コンストラクターを明示的にマークすることの欠点はありますか?
explicit
数回、コードをリファクタリングするときに、以前のパラメーターなしのコンストラクターにパラメーターを追加したり、以前のマルチパラメーターコンストラクターからパラメーターを削除したりするときに、キーワードを追加するのを忘れました。explicit
これを防ぐために、引数がいくつあっても、すべてのコンストラクターにマークを付ける習慣があります。(もちろん、私が実際に暗黙の変換を必要とするコンストラクターを除いて。)
これにはマイナス面がありますか?パフォーマンス?コンパイル時間?
c++ - 暗黙的な型変換のためのC++コンストラクタ
私はこれらのコードを持っています:
私が理解したように、明示的なキーワードのないType2の1引数コンストラクターは、Type1オブジェクトまたはint値を暗黙的にType2オブジェクトに変換できることを意味する必要があります。
しかし、最後の行ではt2 = t1; 、MS Visual Studioでこのコンパイルエラーが発生します:
....エラーC2679:バイナリ'=':タイプ'Type1'の右側のオペランドをとる演算子が見つかりません(または受け入れ可能な変換がありません)。
MSVisualStudioがt2=t1を主張しているようです。lhs=Type2およびrhs=Type1の代入演算子と一致する必要があります。rhsを暗黙的にt2にキャストしてから、Type2 = Type2演算子を使用してコピーを実行できないのはなぜですか?
c++ - 明示的な移動コンストラクター?
このexplicit
キーワードは、コピーコンストラクターを除き、1つの引数で呼び出すことができるほとんどすべて のコンストラクターに推奨されます。
コピーコンストラクターの場合、これには用途があります(関数呼び出し、returnなどによる暗黙的なコピーを禁止するため)が、通常必要なものではありません。
移動コンストラクターはどうですか?それらを明示的にするための合理的なユースケースはありますか?ここでの良い習慣は何ですか?
c++ - 暗黙的に定義されたクラスのデストラクタ
開発者によって明示的に宣言されたdestructor
andを持たないクラスの場合を考えてみましょう。この場合、 for a class になることconstructor
を理解しています。では、クラスのオブジェクトが破棄されようとしている場合にのみ、 が であるというのは本当ですか?destructor
implicitly declared
destructor
implicitly defined
コンストラクタの振る舞いも上記と同じです。implicitly defined
クラスのオブジェクトが作成されたときだけですか?
編集
上記のコードでは、~A() が暗黙的に宣言されます。私の質問は、クラスのオブジェクトが次のようにインスタンス化されている場合にのみ、デストラクタの定義が暗黙的に行われるというのが本当かどうかです
それとも、オブジェクトのインスタンス化が行われていない場合でも、暗黙的に定義されていますか?
c++ - この明示的なデストラクタが共有ptrのメモリ破損を引き起こすのはなぜですか?
このコードの何が問題になっていて、どうすれば修正できますか?
このコードは機能しているように見え、次のように出力されます。
しかし、プログラムがクラッシュし、valgrindが常に次のように言うことがあります。
この動作はm_test.reset()行で修正できますが、もっと正しい解決策があると思います...