何时传递指针或shared_ptr

时间:2016-07-17 21:46:12

标签: c++ pointers vector reference shared-ptr

有很多关于通过引用或指针传递以及何时使用指针的问题。

到目前为止,我对这个问题的理解是以下规则:

  • 始终尝试通过引用传递
  • 如果必须
  • ,则通过指针(仅使用指针)

在我的情况下,我必须使用指针来保留多态行为,因为我将传递的对象存储到一个向量中供以后使用(它是一个'add'方法)。
请参阅:C++ Overridden method not getting called

我读过:

所以我的问题是这样的:
如果我尝试传递已包含在shared_ptr中的指针以添加到矢量,我应该

  • 传递对要添加到向量中的shared_ptr的引用(因为另一种方法不实用)

  • 使用shared_ptr :: get获取实际指针,传递该指针,使用shared_ptr :: reset重新包装它,然后将其添加到向量中? (因为如果我转让所有权,我应该只传递智能指针)

代码:

//method definition
void addToVector(shared_ptr<Object>& obj) {
    myVector.push_back(obj);
}
//call
shared_ptr<Object> myObj = make_shared<Object>();
addToVector(myObj);

//method definition
void addToVector(Object* obj) {
    shared_ptr<Object> toAdd;
    toAdd.reset(obj);
    myVector.push_back(toAdd);
}
//call
shared_ptr<Object> myObj = make_shared<Object>();
addToVector(myObj.get());

2 个答案:

答案 0 :(得分:2)

  

我必须使用指针来保留多态行为,因为我将传递的对象存储到向量中供以后使用

如果将指向的对象存储在向量中,那么您就不会保留多态行为

  

我应该...使用shared_ptr :: get获取实际指针,传递指针,使用shared_ptr :: reset重新包装它,然后将其添加到向量中?

没有。共享指针可能不会获取已由另一个共享指针拥有的指针的所有权。这将有不确定的行为。

  

(因为如果我转让所有权,我应该只通过智能指针)

如果您打算存储指向该对象的共享指针,那么您 转移(共享)所有权。如果这是你的意图,那么将const引用传递给共享指针,如链接的答案中所述。

如果您不打算共享所有权,那么存储共享指针不是您应该做的。您可能希望存储引用包装器,裸指针或弱指针。你应该如何传递对函数的引用,取决于你选择用它做什么。

答案 1 :(得分:0)

第二个例子是未定义的行为,因此根本不能被认为是一种有效的方法:

void addToVector(Object* obj) {
    shared_ptr<Object> toAdd;
    toAdd.reset(obj); // n.b. could just use shared_ptr(obj) ctor
    myVector.push_back(toAdd);
}
shared_ptr<Object> myObj = make_shared<Object>();
addToVector(myObj.get()); // UB

myObj拥有它的指示对象,然后使用get()形成指向该指示对象的原始指针,然后在{{{{}}创建一个具有相同指示对象的新shared_ptr,会发生什么? 1}}。现在你有两个智能指针引用同一个对象,但两个智能指针彼此不知道,所以每个都会销毁对象,这是双重自由的,这是未定义的行为。