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

+0

是否要创建对象的副本或将参考/指针存储到原始对象? –

+0

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

回答

2

既然你说,

我希望有一个指针/引用原文。

唯一的选择是删除shared_ptr和使用非所属指针:(删除所有const■如果你需要一个非const指针)

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); 
} 

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); 
} 
2

如果您知道别人是管理矢量元素的一生,然后用std::vector<const BaseClass*>作为类型,并推动要素矢量时使用&input0等。

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

如果你想保留你的引用,那么你总是可以把它们放在std::reference_wrapper;设置std::vector<std::reference_wrapper<const BaseClass>>作为类型。但所有权问题仍然普遍存在;你可能会得到一个悬挂引用的向量。

+0

这是我最初的想法,但我不想担心所有权问题。 – user1876942

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())); 

这告诉用户,你要采取该对象的共享所有权。

+0

@KonradRudolph 1.我没有看到,除了部分,我在那里解释了为什么API可能会误导用户。你在这里是对的。我将编辑我的评论来代替使用'std :: make_shared()'。 – cdonat

+0

感谢您纠正此问题。关于(1),你是对的,你的回答明确地描述了警告。我不知道为什么我没有看到。 –