在 C++ Qt 中删除原始指针的替代方法
Alternative to deleting raw pointer in C++ Qt
所以我有以下用 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();
}
现在你可以看到我正在删除原始指针 Post*
,但是我想知道我上面的内容是否可以用另一种不需要使用 deleteLater()
的方式实现.
如果 post
不会比 this
长寿,并且 总是 将成为 this
的 child (这意味着它永远不会重新设置)然后你可以将实例存储在 unique_ptr<Post>
:
的 vector
中
class This: /* ... */ {
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
现在您的代码可以省略删除:
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.
(这假定 post->deleteLater()
可以在您的原始代码中替换为 delete post
。您似乎没有理由使用 deleteLater()
而不是仅仅调用delete
直接。)
当this
被销毁时,它的成员将在调用基础class析构函数之前先被销毁。所以 post_vec_
将首先被销毁,这意味着它包含的智能指针将删除它们管理的 Post
objects。那些 objects 的析构函数将从它们的 parents 中注销 objects,因此不会发生 double-deletion。这就是为什么这个答案要求这些 objects 不能比 this
长寿并且不能重新成为父母。
最后一点,如果你不想在 This
header 中公开 Post
class,你可以直接声明它:
class Post;
class This: /* ... */ {
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
unique_ptr
仍然可以使用它,只要你在 .cpp
文件中实现你的析构函数。如果你没有析构函数,那么你可以使用默认的,但是你需要在.cpp
文件中默认它:
class Post;
class This: /* ... */ {
public:
// ...
~This() override;
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
在 .cpp
文件中:
This::~This() = default;
所以我有以下用 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();
}
现在你可以看到我正在删除原始指针 Post*
,但是我想知道我上面的内容是否可以用另一种不需要使用 deleteLater()
的方式实现.
如果 post
不会比 this
长寿,并且 总是 将成为 this
的 child (这意味着它永远不会重新设置)然后你可以将实例存储在 unique_ptr<Post>
:
vector
中
class This: /* ... */ {
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
现在您的代码可以省略删除:
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.
(这假定 post->deleteLater()
可以在您的原始代码中替换为 delete post
。您似乎没有理由使用 deleteLater()
而不是仅仅调用delete
直接。)
当this
被销毁时,它的成员将在调用基础class析构函数之前先被销毁。所以 post_vec_
将首先被销毁,这意味着它包含的智能指针将删除它们管理的 Post
objects。那些 objects 的析构函数将从它们的 parents 中注销 objects,因此不会发生 double-deletion。这就是为什么这个答案要求这些 objects 不能比 this
长寿并且不能重新成为父母。
最后一点,如果你不想在 This
header 中公开 Post
class,你可以直接声明它:
class Post;
class This: /* ... */ {
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
unique_ptr
仍然可以使用它,只要你在 .cpp
文件中实现你的析构函数。如果你没有析构函数,那么你可以使用默认的,但是你需要在.cpp
文件中默认它:
class Post;
class This: /* ... */ {
public:
// ...
~This() override;
// ...
std::vector<std::unique_ptr<Post>> post_vec_;
};
在 .cpp
文件中:
This::~This() = default;