13

このクラスを書いてみました

#include <memory>

class ContainerUnique
{
public:

    ContainerUnique(void);
    ~ContainerUnique(void);

private:
    std::unique_ptr<UniqueElement> u;
};

UniqueElement は、別の場所で定義された POD クラスです。コンストラクタ本体を次のように定義します。

ContainerUnique::ContainerUnique(void)
{
    auto tmp = new UniqueElement(1);

    this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile?
}

そしてそれは例外なく遵守します。ContainerUniqueプログラムを実行すると、コンストラクターが呼び出された後uに null ポインターが含まれていることがわかりました。

これは意図した動作ですか?そして、実際に呼び出している unique_ptr メソッドは何ですか?

4

3 に答える 3

21

これは VS2010 の既知の問題unique_ptrです。最適化 (空のベースの最適化) として空の場合、デリータからパブリックに継承します。public 継承の欠点は、deleter のすべてのメンバーが の利用可能なメンバーにもなることです。unique_ptrこの場合operator()(T*)、ポインターを削除します。

バグは、継承がプライベートに変更された VS2012 のライブラリで修正されています。

于 2012-07-02T14:32:50.740 に答える
9

default_delete< UniqueElement >::operator () ( UniqueElement* ptr )uniqe_ptr はそれから派生し (空の基底クラスの最適化の恩恵を受けるため)、 を削除するため、を呼び出していptrます。標準で禁止されているとは思いませんが、これは意図した動作ではありません。

于 2012-07-02T14:34:26.293 に答える
2

次のように行う必要があります

ContainerUnique::ContainerUnique(void):u(new UniqueElement(1)) {
}
于 2012-07-02T14:31:38.893 に答える