问题描述
我正在尝试封装 Engine 实现类的细节。为此,我将返回抽象类的 std::unique_ptr
(在我的例子中为 IEngine
)而不是 Engine
。但由于编译错误,我无法做到这一点。我可以返回原始引用并且它可以工作,但是 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>
不同的类型,因此您要求返回对临时对象的引用。
std::unique_ptr
唯一拥有它指向的对象,因此即使您删除了引用,从现有的 {{1} 创建一个 std::unique_ptr<IEngine>
也是不正确的} 你大概想保持不变。
您不应该在这里暴露 std::unique_ptr<Engine>
。我不确定您是否应该在这里公开 std::unique_ptr
。我也很困惑为什么您需要在 IEngine
中使用具体的 Engine
类型,但外部世界需要对 指向 Car
的指针进行可变访问。
相反,我希望得到类似的结果:
IEngine
,
我正在尝试封装 Engine 实现类的详细信息。
返回对私有成员的非常量引用很少是正确的做法。在任何情况下,它都与数据封装相反。一旦调用者有了参考,他们就可以随心所欲地使用它。返回非 const 引用对于方便访问方法(例如 std::vector::operator[]
)是有意义的。 std::vector::operator[]
的目的不是对调用者隐藏元素。还有其他方法可以让您掌握它。相反 std::vector::operator[]
是为了更方便地访问元素。封装不是。
也不清楚为什么要从 unique_ptr
返回 Get
。当不需要所有权转移时,不需要返回智能指针。
我可以返回原始引用
是的,那完全没问题:
#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;
}