2

我有一个像

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 并传递指针吗?我想尽可能少地改变。

4

3 回答 3

3

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

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

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

于 2015-10-20T12:20:12.847 回答
2

既然你说了,

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

唯一的选择是删除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指针,请删除所有s。)

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

但是,如果我误解了您,并且您实际上想将对象的(共享)所有权授予您的向量,则还需要通过共享指针将对象传递给您的函数:

void Element::setNodes(std::shared_ptr<BaseClass> input0, std::shared_ptr<BaseClass> input1) {
    m_inputNode.push_back(input0);
    m_inputNode.push_back(input1);
}
于 2015-10-20T12:29:38.217 回答
1

您必须将指针指向您的元素:

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

因此shared_ptr<>s 必须指向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()));

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

于 2015-10-20T12:46:57.087 回答