次のプログラムを検討してください。
#include <string>
struct S {
S (){}
private:
void *ptr = nullptr;
std::string str = "";
};
int main(){}
-Weffc++
これは、 GCC 4.7.1でコンパイルすると、次のように吐き出されます。
警告:「structS」にはポインタデータメンバーがあります[-Weffc ++] 警告:ただし、「S(const S&)」をオーバーライドしません[-Weffc ++] 警告:または'operator =(const S&)' [-Weffc ++]
この例のいくつかのことを除いて、これは通常は問題ありません。
コンストラクター、ポインター宣言、または文字列宣言のいずれかをコメントアウトすると、警告が消えます。ポインタだけで十分だと思うので、これは奇妙ですが、そうではありません。さらに、文字列宣言を整数宣言に変更すると、それも非表示になるため、文字列(またはおそらく他の選択クラス)が含まれている場合にのみ表示されます。このような状況で警告が消えるのはなぜですか?
多くの場合、この警告は、ポインターが実行しているのが既存の変数(ほとんどの場合OSによって維持されている)を指しているときに発生します。、、
new
はありませんdelete
。このような場合、ハンドル付きのクラスをコピーするときに、深いコピーは必要ありません。両方のハンドルが同じ内部オブジェクト(たとえば、ウィンドウなど)を指すようにします。コピーコンストラクターと代入演算子を不必要にオーバーロードしたり、警告を完全に無効にしたりせずに、コンパイラーにこれを認識させる方法はあります#pragma
か?三つのルールが適用されないのに、そもそもなぜ私は悩まされているのですか?