問題タブ [rule-of-three]

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.

0 投票する
2 に答える
620 参照

c++ - Rule of 3 (または Rule of 5 C++11) をチェックする静的解析ツールはありますか?

私は現在、砂の土台の上に構築されたコードベースに取り組んでいます。

テスト済みと思われるライブラリには、「3 の規則」に違反する多数のクラスがあります。ほとんどの場合、非自明なデストラクタが宣言されていますが、コピー コンストラクタまたは代入演算子のいずれかが欠落しています。

クラスが 3 の規則に違反したときに警告するコンパイラ フラグ (gcc) または静的解析ツールはありますか?

現在、GCC バージョン 4.4 で Coverity を使用しています。

0 投票する
1 に答える
1044 参照

c++ - C++ : コピー アンド スワップ イディオム、代替コンストラクター

注: この質問は前の質問に続きます。新しい質問として引き続き質問しても問題ないことを願っています。

次のようなツリー クラスの「3.5 ビッグ ルール」(コピー アンド スワップ イディオム) を実装しようとしています。

私はこのガイドラインに従うように努めてきました。私のコピー代入演算子は次のようになります。

パブリックコンストラクターを機能させるのに苦労しています。誰かが私に次のようなことを提案しました:

このアイデアが機能するかどうかはわかりません。いずれにせよ、コンパイラから次のエラーが表示されます。

代わりに、次のアイデアを試しました。これはうまくいくと思いました。

しかし、それも機能していないようです。*this = Tree(&aTemp, &bTemp, depth, depth)問題は、コピー代入演算子( )を呼び出すときにコピーコンストラクターを呼び出す必要があることだと思います(コピー代入演算子の引数は値渡しであるため)が、これが行われていないようです。私はなぜなのか理解していない。

助けてくれてありがとう!

0 投票する
1 に答える
122 参照

c++ - コピー構築または代入によるコピー後にクラス メンバーが文字化けする (ときどき)

私のクラスNRRanNormalは正規分布確率変数を表しています。デフォルトでは、インスタンスは平均 0 および stdev 1 (つまり、標準の正規確率変数) で正規分布されます。

オブジェクトをコピーNRRanNormalすると、コピーされた (またはコピー コンストラクターを介して構築された) オブジェクトの平均値と標準偏差が文字化けしてナンセンスになることがありますこの文字化けの原因を見つけるのに苦労しています。

テスト目的で、次の関数は特定のNRRanNormalオブジェクトの平均値と標準偏差を表示します。

それでは、次の 4 つのケースで何が起こるか見てみましょう。

上記のステートメントの出力は次のとおりです。

ご覧のとおり、オブジェクト ( foo) をインスタンス化するだけで、期待どおりに機能します。

今、私がするときNRRanNormal bar1 = foo;、オブジェクトbar1は文字化けしています。しかし、私が行うNRRanNormal bar2; bar2 = foo;と、オブジェクトbar2は文字化けしません。これは私を困惑させます。のようなステートメントブロックだと思いました

コンパイラによって実際にステートメントブロックに変換されます

したがって、すぐ上に書いたことが間違っていない限り、bar1とはまったく同じメンバー値bar2を持つ必要があるようです。しかし、上に貼り付けた出力からわかるように、文字化けしていますが、問題ありません。 bar1bar2

どうすればいいの?

bar3文字化けしていることにも気付くでしょう。これが同じ問題なのか、別の問題なのかわかりません。


のインターフェースと実装の簡略化されたバージョンを次に示しますNRRanNormal

Normaldev構造体は Numerical Recipes 3d Edition からのものです。

コピー代入演算子またはコピー コンストラクターに何か問題がありますか?


これはNormaldev、独自の計算を取り除いたものです。

0 投票する
2 に答える
745 参照

c++ - C++ - オブジェクトへのポインターのベクトルの場合、再割り当てによってオブジェクトの削除とコピーが発生しますか?

これまでの私の理解では、クラスオブジェクトのベクトルがある場合、ベクトルのメンバーを消去すると、通常、ベクトルはメモリの連続性を維持するためにオブジェクトの一部を再割り当てします。したがって、ベクター メンバーを消去するときにすべてを保持するには、3 つのルール (デストラクタ、コピー コンストラクタ、およびコピー代入演算子) を実装する必要があります。

ただし、クラスオブジェクトへのポインターのベクトルの場合、結果はあまり明確ではありません。メンバーを消去すると、確かにC++はポインターをコピーするだけで十分にスマートです-ポインター(およびそれが指すクラスオブジェクト)を狂ったように削除してから、それとそれが指すオブジェクトを再作成しませんか?

そうでない場合、誰かがこのばかげたことを私に説明できますか?

0 投票する
2 に答える
2544 参照

c++ - クラスにユーザー宣言のデストラクタが含まれている場合、コピー コンストラクタはどうなりますか?

セクション 12.8/7 の標準は次のように述べています。

クラス定義でコピー コンストラクターが明示的に宣言されていない場合は、暗黙的に宣言されます。クラス定義でムーブ コンストラクターまたはムーブ代入演算子が宣言されている場合、暗黙的に宣言されたコピー コンストラクターは削除済みとして定義されます。それ以外の場合は、デフォルト (8.4) として定義されます。クラスにユーザー宣言のコピー代入演算子またはユーザー宣言のデストラクタがある場合、後者のケースは推奨されません 。したがって、クラス定義については

コピー コンストラクターが暗黙的に宣言されています。ユーザーが宣言したコンストラクターが後で次のように定義されている場合

その要点がわかりません クラスにユーザー宣言のコピー代入演算子またはユーザー宣言のデストラクタがある場合、後者のケースは非推奨です。この例では、標準はユーザー宣言のコピー代入演算子もデストラクタも提供していません。デストラクタまたはコピー代入演算子を宣言するとどうなりますか? 私は次のようにそれをやろうとしました:

デモ

ただし、この例では、暗黙的に宣言されたコピー コンストラクターがまだあります。そのルールの実際の意味は何ですか?

次のように書けば、と思いました。

デモ

コピー コンストラクターは明示的に削除されません。しかし、そうではありません。

0 投票する
2 に答える
69 参照

c++ - 解放されたメモリ ポインタでのビッグ 3 リークによる C++ エラーが割り当てられませんでした (重複していません)

コードが正しく実行されず、修正方法がわかりません。これは、3 のルールとは何かを尋ねる人への重複した質問ではありません。なぜなら、この投稿は、ポインター ポインター配列を使用しているこの投稿のように、私の質問を解決するのに役立たないからです。大きな 3 つの関数で何が間違っていたのかわかりませんが、誰かが私の間違いを修正するのを手伝ってくれますか? コンパイラは、delete[] matrix[i]; を強調表示しています。for ループ内の i=2 の場合のデストラクタ内

私のヘッダーファイルには次のものがあります:

0 投票する
2 に答える
195 参照

c++ - ルール・オブ・スリーエクササイズの予想外の結果

私は自由な時間に C++ の基礎を学び、本の演習に従っています。まず、行として 9 を入力し、列として 8 を入力すると、malloc 解放エラーが発生します。第二に、出力として 0 を取得します。入力内容がわかりません。3 のルールを強化できるので、プログラムを書きたいと思います。もちろん宿題ではありません。また、難しい質問で効率的な質問だと思います。質問に答えていただけると助かります。私はグーグルで検索したので、解決策について中途半端なことを見つけることができません。また、コピー コンストラクタ、代入演算子、およびデストラクタをチェックして、エラーの場所を教えてもらえますか?

コンストラクターでこの表示からのアイデアを使用して、double の 2 次元動的配列を実装するクラス TwoD を記述します。動的配列を指す double へのポインター型のプライベート メンバーと、MaxRows と MaxCols である 2 つの int (または unsigned int) 値が必要です。デフォルトの行と列の最大サイズを選択するデフォルトのコンストラクターと、プログラマーが行と列の最大サイズを設定できるパラメーター化されたコンストラクターを提供する必要があります。さらに、特定の行と列のエントリを設定できる void メンバー関数と、特定の行と列のエントリを double 型の値として返すメンバー関数を提供する必要があります。注意: [ ] をオーバーロードすることは (詳細に応じて) 困難または不可能であるため、2 次元配列に対して希望どおりに機能します。したがって、通常の関数表記法を使用してアクセサー関数とミューテーター関数を使用するだけです。+ 演算子をフレンド関数としてオーバーロードして、2 つの 2 次元配列を追加します。この関数は、左側のオペランド TwoD オブジェクトの i 行 j 列の要素と、右側のオペランド TwoD オブジェクトの i 行 j 列の要素の和を i 行 j 列の要素とする TwoD オブジェクトを返す必要があります。コピー コンストラクター、オーバーロードされた演算子 =、およびデストラクターを提供します。データを変更しないクラス メンバー関数を const メンバーとして宣言します。左側のオペランド TwoD オブジェクトの j 列要素と、右側のオペランド TwoD オブジェクトの i 行、j 列要素。コピー コンストラクター、オーバーロードされた演算子 =、およびデストラクターを提供します。データを変更しないクラス メンバー関数を const メンバーとして宣言します。左側のオペランド TwoD オブジェクトの j 列要素と、右側のオペランド TwoD オブジェクトの i 行、j 列要素。コピー コンストラクター、オーバーロードされた演算子 =、およびデストラクターを提供します。データを変更しないクラス メンバー関数を const メンバーとして宣言します。

私の努力