配列を関数に渡し、毎回「std :: unique_ptr」を書き込まないようにし、インライン構築を可能にするために、配列のエイリアスを作成するtypedef(ItemList)を導入しています。
#include <iostream>
#include <memory>
class Base {
public:
Base()
{
std::cout << "Base ctor" << std::endl;
};
virtual ~Base()
{
std::cout << "Base dtor" << std::endl;
};
};
typedef std::unique_ptr<Base> ItemList[];
template<typename T>
class Derived : public Base {
T val;
public:
Derived(T i)
{
val = i;
std::cout << "Derived ctor" << val << std::endl;
};
~Derived()
{
std::cout << "Derived dtor" << val << std::endl;
};
};
void dummyFunc(ItemList)
{
}
void testFunc()
{
dummyFunc(ItemList{
std::make_unique<Derived<int>>(2),
std::make_unique<Derived<float>>(3.0f)
});
}
//Entry point
int main()
{
testFunc();
return 0;
}
これは、デバッグビルドと印刷で意図したとおりに機能します。
Base ctor
Derived ctor2
Base ctor
Derived ctor2
Derived dtor2
Base dtor
Derived dtor2
Base dtor
ここまでは順調ですね。しかし、これをリリースモード(すべてのネイティブコンパイラを使用)でビルドすると、次のようになります。
Base ctor
Derived ctor2
Base ctor
Derived ctor3
Derived dtor2
Base dtor
配列の2番目の項目は、配列のライフサイクルを終了しても破棄されません。私が期待するようにそれを機能させる唯一の方法は、C ++ 03スタイルの初期化またはデバッグモードを使用することです。
ItemList tmpList = {
std::make_unique<Derived<int>>(2),
std::make_unique<Derived<float>>(2.0f)
};
dummyFunc(tmpList);
これにより、意図した動作が発生します(すべてのデストラクタが呼び出されます)。
私はこれを他のコンパイラでまだテストしていませんが、これは予想される動作ですか?私は何を間違っているのですか、それとも何かが足りないのですか?
更新:
興味深いことに、dtorはBaseインスタンスで期待どおりに呼び出されます。
dummyFunc(ItemList{
std::make_unique<Base>(),
std::make_unique<Base>()
});
出力;
Base ctor
Base ctor
Base dtor
Base dtor
また、配列を初期化するだけで(関数呼び出しなしで)、関数呼び出しの場合と同じように動作します。
Visual Studio 2015に切り替えます。これは、VS2013コンパイラの実装バグである可能性があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加