我有一些代码看起来像这样
class Interface
{};
class Contained;
class Container
{
public:
Container() : m_contained(std::make_shared<Contained>(*this))
{
}
std::shared_ptr<Interface> get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
private:
std::shared_ptr<Contained> m_contained;
};
class Contained final : public Interface
{
public:
Contained(Container& container) : m_container(container)
{
}
private:
Container& m_container;
};
我被要求更改
get_contained
以返回参考,所以我天真地认为这样做
std::shared_ptr<Interface>& get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
编译失败
错误:无法将“std::shared_ptr&”类型的非常量左值引用绑定到“std::shared_ptr”类型的右值
所以我添加了
const
const std::shared_ptr<Interface>& get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
现在我失败了
错误:返回对临时 [-Werror=return-local-addr] 的引用
然后我又尝试了几个“修复”
class Container
{
public:
Container()
{
m_contained = std::make_shared<Contained>(*this);
}
const std::shared_ptr<Interface>& get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
private:
std::shared_ptr<Contained> m_contained{};
};
和
class Container
{
public:
Container()
{
m_contained.reset(new Contained(*this));
}
const std::shared_ptr<Interface>& get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
private:
std::shared_ptr<Contained> m_contained{};
};
在绝望中
class Container
{
public:
Container()
{
std::shared_ptr<Contained> ptr = std::make_shared<Contained>(*this);
m_contained = ptr; // also with std::move, but same result
}
const std::shared_ptr<Interface>& get_contained()
{
return std::static_pointer_cast<Interface>(m_contained);
}
private:
std::shared_ptr<Contained> m_contained{};
};
在同一问题上全部失败,无法将左值引用返回到临时值。 我不明白正确初始化的类的成员怎么可能是临时的
我认为这不能通过这种方式解决,因为虽然指向派生类的指针也是指向基类的指针(简化的),但保存派生类的
shared_ptr
绝不会通过继承与shared_ptr
持有基类。
因此没有办法将一个转换为另一个,并且任何伪转换实际上都会创建一个新副本,不幸的是这是暂时的。
如果我可以提出任何建议,以下解决方案可能会起作用:
void get_contained(std::shared_ptr<Interface>& retval)
{
retval = std::static_pointer_cast<Interface>(m_contained);
}