我正在为我的Qt项目使用共享指针,但是当我通过共享指针调用<div class="container">
<div class="block left">
<h5>New</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sollicitudin purus sapien, a scelerisque neque.</p>
</div>
<div class="block right">
<h5>Heading</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sollicitudin purus sapien.</p>
</div>
<div class="block left">
<h5>Cras conva</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sollicitudin purus sapien.</p>
</div>
<div class="block right">
<h5>Cras nita</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sollicitudin purus sapient.</p>
</div>
</div>
时,我遇到了分段错误。
我这样称呼它:
setLayout()
函数 model->getBody()->setLayout(layoutTemplate.get());
返回getBody()
:
std::shared_ptr
我尝试使用std::shared_ptr<QWidget> MainTemplate::getBody()
{
return std::shared_ptr<QWidget>(ui->body);
}
代替QSharedPointer
,但这给了我相同的结果。
为什么我的指针被删除?
答案 0 :(得分:2)
由于shared_ptr只会在下一次尝试使用ui-&gt; body时直到该语句的结尾 1 ,否则它将被删除。
您可能不希望在getter中创建新的共享所有权。相反,任何得到的都应该作为shared_ptr存在,并且getter可以返回一个副本(shared_ptr)。
或者,在您不转移所有权的情况下,原始指针(其中body可以为null)或引用(其中body不能为null)更合适。指针/引用的常见警告仍然适用于指向/引用的对象。
答案 1 :(得分:2)
智能指针代表对象的所有权。 shared_ptr
特别代表一个由多个实体拥有的对象,并且必须存在,直到每个人都使用它为止。每当指向一个对象的最后一个shared_ptr
被销毁时,它指向的对象也会被销毁。正确使用shared_ptr
是:
std::shared_ptr<T> ptr_a(new T); // Create a T and immediately pass it to shared_ptr
std::shared_ptr<T> ptr_b = std::make_shared<T>(); // Same effect but more efficient
ptr_a = ptr_b; // smart pointer to smart pointer assignment (never existing raw to smart)
ptr_a.reset(new T); // This is fine.
ptr_a = std::make_shared<T>(); // Same as previous line. Again more efficient
//... eventually ptr_a and ptr_b go out of scope and handle deleting their objects
请注意,在所有重新分配的示例中,ptr_a
检查了引用计数并删除了保留的对象(如果它是指向它的最后一个shared_ptr
。
通常,您只想在创建时将原始指针传递给智能指针。您所做的是将对象的所有权传递给临时智能指针。在声明之后,临时shared_ptr
被销毁,并且由于没有制作它的副本,它认为它应该销毁ui->body
。通常你想要做的只是通过非const引用返回body
,或者只是不返回它并为其参数提供setter函数。
QWidget& MainTemplate::getBody()
{
return ui->body;
}
但是,如果有某种原因要求身体需要能够超过其阶级(可疑,除非已经做出可疑的设计决定),你需要将身体本身设为shared_ptr
并按值返回。这将创建shared_ptr
的副本,并保证最后一个将销毁该对象。但是你必须在构造完成后不要使用原始指针,你不能手动尝试删除它。
UI { // whatever class MainTemplate::ui points to
private:
std::shared_ptr<<QWidget> body;
...
}
MainTemplate {
public:
std::shared_ptr<QWidget> MainTemplate::getBody()
{
return ui->body;
}
}
同样,如果您的课程以实际方式定义,我认为不需要这样做。此外,如果ui
不属于某个类,则可以使shared_ptr
成为shared_ptr<UI>
,并返回该值而不是其正文。然后,让调用者通过返回的inputs
访问正文。