有很多关于通过引用或指针传递以及何时使用指针的问题。
到目前为止,我对这个问题的理解是以下规则:
在我的情况下,我必须使用指针来保留多态行为,因为我将传递的对象存储到一个向量中供以后使用(它是一个'add'方法)。
请参阅:C++ Overridden method not getting called
我读过:
所以我的问题是这样的:
如果我尝试传递已包含在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());
答案 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}}。现在你有两个智能指针引用同一个对象,但两个智能指针彼此不知道,所以每个都会销毁对象,这是双重自由的,这是未定义的行为。