Return unique_ptr 里面有摘要 class

Return unique_ptr with abstract class inside

我正在尝试封装引擎实现的细节 class。为此,我 returning std::unique_ptr 抽象 class(在我的例子中是 IEngine)而不是 Engine。但由于编译错误,我无法做到这一点。我可以 return 原始参考并且它可以工作但是 unique_ptr 可以吗?提前致谢。

class IEngine
{
public:
    virtual ~IEngine() = default;

    virtual void Start() = 0;
};

class Engine : public IEngine
{
public:
    void Start() override {}
};

class Car
{
    std::unique_ptr<Engine> m_engine;

public:

    std::unique_ptr<IEngine>& Get() { return m_engine; } // Here is compile error
};

int main()
{
    Car lambo;
}

std::unique_ptr<IEngine> 是与 std::unique_ptr<Engine> 不同的类型,因此您要求 return 对临时对象的引用。

std::unique_ptr 唯一拥有 它指向的对象,因此即使您删除了引用,从您可能希望保持不变的现有 std::unique_ptr<Engine>

你不应该在这里暴露 std::unique_ptr。我不确定您是否应该在这里公开 IEngine。我也很困惑为什么你需要 Car 中的具体 Engine 类型,但外部世界需要可变访问指向 IEngine[=31= 的 指针].

我会期待这样的事情:

class Car
{
    std::unique_ptr<IEngine> m_engine;

public:

    void TurnIgnition() { m_engine->Start(); }
};

I am trying to encapsulate details of the Engine implementation class.

返回对私有成员的非常量引用很少是正确的做法。在任何情况下,它都与数据封装相反。一旦调用者有了引用,他们就可以随心所欲地使用它。返回非 const 引用对于方便访问方法(例如 std::vector::operator[])很有意义。 std::vector::operator[] 的目的不是向调用者隐藏元素。还有其他方法可以获得它。而是 std::vector::operator[] 是为了更方便地访问元素。封装不是。

也不清楚为什么要 return 来自 Getunique_ptr。当不需要转移所有权时,不需要 returned 智能指针。

I could return raw reference

是的,非常好:

#include <memory>

class IEngine
{
public:
    virtual ~IEngine() = default;

    virtual void Start() = 0;
};

class Engine : public IEngine
{
public:
    void Start() override {}
};

class Car
{
    std::unique_ptr<Engine> m_engine;

public:

    const IEngine& Get() { return *m_engine; } // Here is compile error
};

int main()
{
    Car lambo;
}