简体   繁体   English

在C ++ Qt中删除原始指针的替代方法

[英]Alternative to deleting raw pointer in C++ Qt

So I have the following piece of code written in Qt C++: 因此,我有以下用Qt C ++编写的代码:

// Post* derives from QObject
Post* post = new Post(this);
QString url;

ParseResult result = parse(url, post); // this function takes a Post* and modifies it

// if result is succesfully parsed
if(result == ParseResult::Success){
    // add the post to a std::vector<Post*> which is a member of the class
}
else{
    post->deleteLater();
}

Now as you can see I am deleting the raw pointer Post* , however I was wondering if what I have above could be implemented in another way which wouldn't require the use of deleteLater() . 现在,您可以看到我正在删除原始指针Post* ,但是我想知道是否可以用不需要使用deleteLater()另一种方式来实现上面的deleteLater()

If post is not going to outlive this , and is always going to be a child of this (meaning it will never get reparented) then you can store the instances in a vector of unique_ptr<Post> : 如果post不会活得比this ,并始终将是一个孩子this (这意味着它永远不会重设父),那么你可以实例存储在一个vectorunique_ptr<Post>

class This: /* ... */ {
// ...
    std::vector<std::unique_ptr<Post>> post_vec_;
};

Now your code can omit the deletion: 现在,您的代码可以省略删除:

auto post = std::make_unique<Post>(this);
QString url;

ParseResult result = parse(url, post.get());
if (result == ParseResult::Success) {
    post_vec_.push_back(std::move(post));
    // 'post' was moved from, so it's just a nullptr now.
}

// No 'else' needed. 'post' is going to be deleted when it goes out of scope.

(This assumes that post->deleteLater() could have been replaced with delete post in your original code. It doesn't seem like you have a reason to use deleteLater() rather than just calling delete directly.) (这假设在原始代码中post->deleteLater()可能已由delete post替换。似乎您没有理由使用deleteLater()而不是直接调用delete 。)

When this is destroyed, its members are going to be destroyed first before calling the base class destructor. this被摧毁,其成员将要调用基类的析构函数之前,首先摧毁。 So post_vec_ is going to get destroyed first, which means the smart pointers it contains are going to delete the Post objects they manage. 因此, post_vec_将首先被销毁,这意味着它包含的智能指针将删除它们管理的Post对象。 The destructors of those objects are going to unregister the objects from their parents, so no double-deletion can happen. 这些对象的析构函数将从其父对象中取消注册这些对象,因此不会发生双重删除。 This is why this answer has the requirement that these objects must not outlive this and must not get reparented. 这就是为什么此答案要求这些对象不能超过this并且不能被重新设置父级的原因。

As a final note, if you don't want to expose the Post class in the This header, you can just forward declare it: 最后一点,如果您不想在This标头中公开Post类,则可以向前声明它:

class Post;

class This: /* ... */ {
// ...
    std::vector<std::unique_ptr<Post>> post_vec_;
};

unique_ptr can still work with that, as long as you implement your destructor in the .cpp file. 只要您在.cpp文件中实现析构函数, unique_ptr仍然可以使用它。 If you don't have a destructor, then you can use the default one, but you need to default it in the .cpp file: 如果没有析构函数,则可以使用默认析构函数,但需要在.cpp文件中将其默认设置:

class Post;

class This: /* ... */ {
public:
    // ...
    ~This() override;

// ...
    std::vector<std::unique_ptr<Post>> post_vec_;
};

In the .cpp file: .cpp文件中:

This::~This() = default;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM