ライブラリでは、クラスCのファクトリメソッドで作成されたクラスAがあります。返されたオブジェクトは、静的メンバ私の問題は、戻り値の最適化は、少なくともVisual Studioでは、XCode(clang)で期待どおりに動作しないようです。何が起こるかは、の前にクラスAのdtorがと呼ばれ、定義された移動割り当て演算子が使用されるということです。 d-torでは、Aのメモリが解放され、その後はデータが無効になります。ファクトリメソッドと静的変数の割り当てからの戻り値の最適化(Visual Studio)
class A {
public:
A();
A(const A &other);
A(const A &&other);
A& operator = (const A &other);
A& operator = (const A &&other);
};
class B {
private:
static A _a;
struct Initializer {
Initializer();
};
static Initializer _init;
};
と
B::Initializer::Initializer() {
C c;
_a = c.factoryMethod();
}
B::Initializer B::_init;
ファクトリメソッドは非常に簡単です:Aの
A C::factoryMethod() {
A a;
....
return a;
}
return a
でコピーコンストラクタは、D-TORが続く、と呼ばれています。その後、move演算子がトリガされます(Bの_aへの結果の代入時)。
これは、RVOの想定とはかなり反対です。コピーが存在してはいけません。したがって、Bが削除された場合を除いて、破壊されるべきではありません。それで、なぜ期待通りに動かないのですか?
アップデートは、いくつかの試行錯誤の後、私は、Visual StudioとXCodeの中で両方の作品解決策を見つけました。しかし、この質問は、これがどのように機能するのか(なぜ私の場合はそうでないのか)を理解することなので、私はまだ良い答えに興味があります。私が問題を解決するためにしたのは、コピーコンストラクタを完全に削除することだったので、実際には呼び出されませんでした。
2つのコンパイラの動作は、まだ異なります。 VSは移動コンストラクタを使用しますが、XCodeは移動コンストラクタを使用しませんが、何があっても定義されている必要があります。もう1つの奇妙な効果は、私は今VSで2つの移動を持っていることです(移動コンストラクタとその後、静的メンバーvarに割り当てるときの移動割り当て)。 XCodeには移動割り当てのみがあります。
まず、 'A(const && other);'は有効な構文ではないため、コンパイルしないでください。第2に、移動コンストラクタは通常、非const rvalue参照をとります。あなたはたぶん 'A(A && other);を意味しています;代入演算子と同様です。 –
[私のために働く](http://rextester.com/KUY47394)と思われます。私は問題を見ない。 –
はい、構文が間違っていました(私はそれを更新しました)。しかし、あなたの実際の例:私が書いたように、コンパイラに依存するようです。はい、XCode(clang)で意図したとおりに動作しますが、問題を引き起こすのはVisual Studioです。 'return a'は移動コンストラクタではなくコピーコンストラクタで終わり、同じ場所からのdtorコールが続きます。戻り値が静的varに代入されると、移動割り当てが続きます。それはクレイジーです。 Btw。 constかどうかは違いはありません。 –