gpt4 book ai didi

c++ - Qt::make_shared 用于创建 QSharedPtr 和 std::make_shared 用于创建 std::shared_ptr

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:04:08 29 4
gpt4 key购买 nike

正如 Bjarne Stroustrup 的“C++ 之旅”中所述,作为一种已知的 C++14 实践,人们应该避免在代码中使用裸露的 newdelete。标准库提供 std::make_sharedstd::make_unique 用于创建智能指针以立即将分配的对象存储在其中。

但是,不能将这些例程用于非标准智能指针,例如在 Qt 中。 Qt 有自己的内存管理模型(带父对象),但也提供智能指针类,如 QSharedPointerQPointer(尽管后者实际上不是拥有指针)。

我的问题是:创建 std::make_shared 的 Qt 类似物不是很方便吗?像这样,创建 QSharedPtr:

namespace Qt
{
template<class T, class... Args>
QSharedPointer<T> make_shared(Args&&... args)
{
return QSharedPointer<T>(new T(std::forward<Args>(args)...));
}
}

或者像这样,创建QPointer:

namespace Qt
{
template<class T, class... Args>
QPointer<T> make_ptr(Args&&... args)
{
return QPointer<T>(new T(std::forward<Args>(args)...));
}
}

它可以像这样使用:

auto pCancelButton = Qt::make_ptr<QPushButton>("Cancel", this);

这种方法有什么注意事项吗?这种方法有任何公开的用法吗?

更新 我声称只要 QPointer 有用,Qt::make_ptr 就有用,因为它会隐藏 new 运算符并确保只为继承 QObject 的对象调用 new。 Qt 用户做了很多 new,但是通过这种方式我们可以确定 new 只在 Qt 上下文中使用。关于这个想法有什么争论吗?

最佳答案

make_shared 等功能严格依赖于完美转发 功能,该功能仅在 C++11 和通用(转发)引用引入后可用。话虽如此,如果没有完美转发,使用此功能可能效率低下。 Qt 比最近的 C++ 标准要老得多,因此它直到 Qt 5.1 才可用(就像以前你必须使用 Qt 的内部预处理宏,如 SIGNALSLOT用于建立连接)。

Qt 5.1 已经为 QSharedPointer 提供了自己的智能指针实现。 .

那个静态create成员函数可以如下使用:

auto ptr = QSharedPointer<QPushButton>::create("Cancel", this);

但注意描述:

Note: This function is only available with a C++11 compiler that supports perfect forwarding of an arbitrary number of arguments. If the compiler does not support the necessary C++11 features, you must use the overload that calls the default constructor.

使用 make_sharedcreate 函数比使用 new 直接调用构造函数分配内存有两个主要优点:

  1. 那个特殊的完美转发函数可以在单个系统调用中为存储对象引用计数器分配内存。

  2. 内存分配与调用上下文分离,因此您可以避免在构造另一个对象时抛出异常时发生内存泄漏,例如函数调用(编译器可以自由选择评估参数的顺序)。考虑:

    foo(QSharedPointer<QPushButton>(new QPushButton("Cancel", this)), MayThrow());

也就是说,如果编译器先执行new QPushButton("Cancel", this)表达式,然后在调用构造函数之前调用MayThrow()函数QSharedPointer,如果MayThrow() 函数抛出异常,则可能会泄漏内存。

关于c++ - Qt::make_shared 用于创建 QSharedPtr 和 std::make_shared 用于创建 std::shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26295238/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com