convert引用共享指针

时间:2015-10-20 12:12:59

标签: c++ object-slicing

我有一个像

这样的功能
void Element::setNodes(const BaseClass& input0, const BaseClass& input1)

通过传递派生类来调用它。

setInputNodes(DerivedClass1, DerivedClass2)

我遇到的麻烦是我想将节点存储在一个向量中。我有这个

std::vector<std::shared_ptr<BaseClass>> m_inputNode;

和函数

void Element::setNodes(const BaseClass& input0, const BaseClass& input1)
{
m_inputNode.push_back(input0);
m_inputNode.push_back(input1);
}

这不起作用,我必须将其存储为指针,否则我会遇到对象切片。我需要更改API并传递指针吗?我希望尽可能少地改变。

3 个答案:

答案 0 :(得分:2)

如果知道其他人正在管理向量元素的生命周期,则使用std::vector<const BaseClass*>作为类型,并在将元素推送到其中时使用&input0等矢量。

这里很难使用std::shared_ptr指针,因为在使用时,您不知道对象是如何创建的。

如果您想保留引用,那么您可以随时将它们括在std::reference_wrapper;将std::vector<std::reference_wrapper<const BaseClass>>设置为类型。但所有权问题仍然普遍存在;你最终可能会得到一个悬挂引用的载体。

答案 1 :(得分:2)

既然你说过,

  

我想要一个原始的指针/引用。

唯一的选择是删除let s = "\(key)" return self[s] as? Bool ?? fall 并使用非拥有指针:

shared_ptr

(如果您需要非std::vector<BaseClass const*> m_inputNode; void Element::setNodes(BaseClass const& input0, BaseClass const& input1) { m_inputNode.push_back(&input0); m_inputNode.push_back(&input1); } 指针,请删除所有const。)

const从根本上表达所有权,这似乎不是您所追求的。

但如果我误解了你并且你真的想要将对象的所有权赋予你的向量,你需要通过共享指针将对象传递给你的函数:

shared_ptr

答案 2 :(得分:1)

你必须把指针指向你的元素:

void Element::setNodes(const BaseClass& input0, const BaseClass& input1)
{
    m_inputNode.push_back(&input0);
    m_inputNode.push_back(&input1);
}

因此shared_ptr<>必须指向const BaseClass。如果您不希望这样,则必须从参数规范中删除const

我不建议根据您的需要使用这样的API。您没有明确调用者,您记得指向对象的指针。当你以后尝试使用它时,他可能会传入堆栈分配的甚至临时对象,这些对象不再有效:

myElement.setNodes(createElement0(), createElement1());

希望明确函数用户的期望。

void Element::setNodes(std::shared_ptr<BaseClass> input0,
                       std::shared_ptr<BaseClass> input1)
{
    m_inputNode.push_back(input0);
    m_inputNode.push_back(input1);
}

现在用户必须明确提供指针:

myElement.setNodes(std::make_shared<Element>(createElement0()),
                   std::make_shared<Element>(createElement1()));

这告诉用户,您将获得该对象的共享所有权。