指向派生对象的基类型指针的 make_unique 的语法是什么?

nm1*_*m17 2 c++ smart-pointers

考虑以下基类和派生类。

class base
{
public:
    int i{9};
    virtual void func()
    {
        cout << "base" << endl;
    }
    virtual ~base()
    {

    }
};

class derived : public base
{
public:
    int i{4};
    void func()
    {
        cout << "derived" << endl;
    }

};
Run Code Online (Sandbox Code Playgroud)

我想创建unique_ptrbase类型derived对象。我知道我能做到

std::unique_ptr<base> ptr{new derived};

但是当我这样做的时候

auto ptr = std::make_unique<base>(derived{});
ptr->func();
Run Code Online (Sandbox Code Playgroud)

这会打印base,这不是我的预期行为。std::make_unique在这种情况下使用的正确方法是什么?另外,为什么auto ptr = std::make_unique<base>(derived{})呢?

Nat*_*ica 5

当你做

auto ptr = std::make_unique<base>(derived{});
Run Code Online (Sandbox Code Playgroud)

make_unique<base>将要创建一个unique_ptr<base>,这意味着它只会创建一个base对象。由于derived是从 base 派生的,因此将其传递给base的复制构造函数是合法的,以便代码编译,但您有一个base,而不是derived.

你需要的是

std::unique_ptr<base> ptr = std::make_unique<derived>();
Run Code Online (Sandbox Code Playgroud)

获取base指向derived对象的指针。这不是您想要的语法,但它可以正常工作。

如果你使用

auto ptr = std::make_unique<derived>();
Run Code Online (Sandbox Code Playgroud)

那么ptr将是 a std::unique_ptr<derived>,而不是 a std::unique_ptr<base>

  • @roulette01它被转发到构造函数,只是因为您使用了`std::make_unique&lt;base&gt;`,所以它只会查看`base`的构造函数来创建`base`对象。由于“衍生”是从“基”派生的,因此它可以调用编译器隐式生成的“基”的“base(const base&amp;)”构造函数。这会将派生对象切片为仅基础部分。 (4认同)