更新以下のバグはVS2012で修正され、期待どおりにnoncopyable
機能します
これは質問であり、情報を提供したり他の人に警告したりして、私と同じトラップに陥らないようにする方法でもあります。noncopyable
基本クラス(ブーストのクラスなど)を使用しても、エクスポートされたクラスでは効果がないようです。 MSコンパイラ。これはMSにとって既知のバグですが、それを知っているプログラマーがたくさんいるとは思えません。ご想像のとおり、これにより、コンパイルすらしてはならないコードを記述できるため、非常に厄介なバグが発生する可能性があります。例(ここにコピーできないクラスのコード:)
dllプロジェクトの典型的なヘッダーファイル。次のコマンドでコンパイルし/D EXPORT_IT
ます。
#ifdef EXPORT_IT
#define mydll __declspec( dllexport )
#else
#define mydll __declspec( dllimport )
#endif
class mydll CantCopyMe : private noncopyable
{
public:
CantCopyMe();
~CantCopyMe();
};
mydll CantCopyMe MakeIt();
ソースファイル:
#include <iostream>
CantCopyMe::CantCopyMe()
{
std::cout << "constructor" << std::endl;
}
CantCopyMe::~CantCopyMe()
{
std::cout << "destructor" << std::endl;
}
CantCopyMe MakeIt()
{
CantCopyMe x;
return x; //oops... this sould not compile nor link but it does
}
アプリケーション:
int main()
{
CantCopyMe x( MakeIt() );
}
出力:
constructor
destructor
destructor
1つのコンストラクタ、2つのデストラクタが呼び出されます。クラスにリソースが効果的に含まれている場合の問題を想像してみてください。
コンパイルは行うがすべきではない使用例を編集します。
CantCopyMe MakeIt()
{
CantCopyMe x;
return x;
}
void DoIt( CantCopyMe x )
{
x.Foo();
}
void SomeFun()
{
CantCopyMe x;
DoIt( x );
}
その他の場合:CantCopyMe MakeIt(){return CantCopyMe(); //致命的なエラーC1001}
CantCopyMe GenerateIt()
{
CantCopyMe x;
return x;
}
CantCopyMe MakeIt()
{
return GenerateIt(); //fatal error C1001
}
CantCopyMe MakeIt()
{
CantCopyMe x;
return CantCopyMe( x ); //fatal error C1001 + cl crashes
}
void DoSomething()
{
CantCopyMe x;
CantCopyMe y = x; //fatal error C1001 + cl crashes
}
質問:
KBの記事では、今後のリリースでの修正について言及しています。誰かがこれがVS2010ですでに修正されているかどうかを確認できますか(またはおそらくVisual Studio 11プレビューで)?
何らかのエラーをトリガーするための回避策はありますか?
return CantCopyMe()
書き込みが内部コンパイラエラーをトリガーするという事実を(ab)使用してみましたが、MakeIt
上記のような関数をコンパイルする場合にのみ条件付きでトリガーする方法を見つけることができませんでした。static_assertをコピー不可能なコピーコンストラクターに入れても、コンパイラーは呼び出されなくても常にコンパイルするため、それはカットされません。