在我的上一个问题获得提示后,我开始编写代码,但是遇到了重载 Scene::addObject 的问题。
为了概括相关部分并使其自包含,尽可能少地提供细节:
- 我有一组从
Interface
继承的对象层级结构,其中有Foo
和Bar
; - 我有一个拥有这些对象的
Scene
; main
中的Foo
应该是unique_ptr
,而Bar
应该是shared_ptr
(出于上一个问题中解释的原因);main
把它们传递给Scene
实例来接管。
最小化的代码示例在此处:
#include <memory>
#include <utility>
class Interface
{
public:
virtual ~Interface() = 0;
};
inline Interface::~Interface() {}
class Foo : public Interface
{
};
class Bar : public Interface
{
};
class Scene
{
public:
void addObject(std::unique_ptr<Interface> obj);
// void addObject(std::shared_ptr<Interface> obj);
};
void Scene::addObject(std::unique_ptr<Interface> obj)
{
}
//void Scene::addObject(std::shared_ptr<Interface> obj)
//{
//}
int main(int argc, char** argv)
{
auto scn = std::make_unique<Scene>();
auto foo = std::make_unique<Foo>();
scn->addObject(std::move(foo));
// auto bar = std::make_shared<Bar>();
// scn->addObject(bar);
}
去掉注释行的结果是:
error: call of overloaded 'addObject(std::remove_reference<std::unique_ptr<Foo, std::default_delete<Foo> >&>::type)' is ambiguous
scn->addObject(std::move(foo));
^
main.cpp:27:6: note: candidate: 'void Scene::addObject(std::unique_ptr<Interface>)'
void Scene::addObject(std::unique_ptr<Interface> obj)
^~~~~
main.cpp:31:6: note: candidate: 'void Scene::addObject(std::shared_ptr<Interface>)'
void Scene::addObject(std::shared_ptr<Interface> obj)
^~~~~
取消注释共享部分并注释掉独特的内容也可以编译,所以我认为问题就像编译器所说的那样,在于重载。然而,我需要这种重载,因为这两种类型都需要存储在某种集合中,并且它们确实被保留为指向基类的指针(可能全部移动到shared_ptr中)。我通过按值传递两个参数来明确表明我在Scene中拥有它们(并增加了shared_ptr的引用计数)。对我来说不太清楚问题究竟出在哪里,我找不到任何其他示例。
std::unique_ptr<Foo>
转换为std::shared_ptr<Scene>
和转换为std::unique_ptr<Scene>
一样好。 - felixunique_ptr
版本已经过时了,因为可以轻松地转换为shared_ptr
。另一种解决方法是不使用重载(至少重命名其中一个方法),这应该提高可读性。 - Marek R