何时通过指针或 shared_ptr

When to pass by pointer or shared_ptr

关于通过引用或指针传递以及何时使用指针,有大量问题被问到。

到目前为止,我对该主题的理解是以下规则:

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

我已阅读:

所以我的问题是:
如果我试图传递一个已经包含在 shared_ptr 中的指针以添加到向量中,我应该

  • 传递对要添加到向量中的 shared_ptr 的引用(因为其他方法很笨拙)

代码:

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

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

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 addToVector()。现在你有两个指向同一个对象的智能指针,但是这两个智能指针不知道彼此,所以每个都会销毁对象,这是双重释放,这是未定义的行为。

I must use pointers in order to retain polymorphic behaviours as I am storing the passed object into a vector for later use

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

Should I ... use shared_ptr::get to get the actual pointer, pass that pointer, re-wrap it using shared_ptr::reset, and then add it to the vector?

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

(because I should only pass smart pointers if I'm transferring ownership)

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

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