简体   繁体   English

Qt :: make_shared用于创建QSharedPtr作为std :: make_shared用于创建std :: shared_ptr

[英]Qt::make_shared for creating QSharedPtr as std::make_shared for creating std::shared_ptr

As stated in Bjarne Stroustrup's "A tour of C++", and as a known C++14 practice, one should avoid naked new and delete in the code. 正如Bjarne Stroustrup的“C ++之旅”中所述,并且作为已知的C ++ 14实践,应该避免在代码中使用裸newdelete Standard library offers std::make_shared and std::make_unique for creating smart pointers to immediately store allocated objects in. 标准库提供了std::make_sharedstd::make_unique用于创建智能指针以立即存储已分配的对象。

However, it is not possible to use these routines for non-standard smart pointers, like in Qt. 但是,不可能将这些例程用于非标准智能指针,例如Qt。 Qt has its own memory management model (with parents), but also provides smart pointer classes like QSharedPointer and QPointer (though the latter is not actually an owning pointer). Qt有自己的内存管理模型(带父QSharedPointer ),但也提供了QSharedPointerQPointer等智能指针类(尽管后者实际上并不是拥有指针)。

My question is: isn't it convenient to create Qt analogs of std::make_shared ? 我的问题是:创建std::make_shared Qt类似物不方便吗? Like this, for creating QSharedPtr : 像这样,创建QSharedPtr

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

Or like this, for creating QPointer : 或者像这样,创建QPointer

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

And it can be used like: 它可以像:

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

Are there any caveats for this approach? 这种方法有什么警告吗? Are there any publicly known usage of this approach? 有这种方法的公开使用吗?

UPDATE I claim that Qt::make_ptr is useful as long as QPointer is useful, because it will hide new operator and make sure new is called only for something that inherits QObject . 更新我声称只要QPointer很有用, Qt::make_ptr QPointer有用,因为它会隐藏new运算符并确保只为继承QObject东西调用new Qt users do a lot of new 's, but in this way we can be sure new is used only in Qt context. Qt用户做了很多new的,但是通过这种方式我们可以确定new只在Qt上下文中使用。 Any arguments on this thought? 关于这个想法的任何争论?

Features such as make_shared strictly rely on the perfect forwarding feature, which is only available since C++11 and the introduction of universal (forwarding) references . 诸如make_shared严格依赖于完美的转发功能,该功能仅在C ++ 11和引入通用(转发)引用时可用。 Having said that, without a perfect forwarding , using this function may be inefficient. 话虽如此,如果没有完美的转发 ,使用此功能可能效率低下。 Qt is quite older than the recent C++ standard, hence it was not available till Qt 5.1 (just like previously you had to use Qt's internal pre-processing macros like SIGNAL and SLOT for making connections). Qt比最近的C ++标准要老,因此直到Qt 5.1才能使用它(就像之前你必须使用Qt的内部预处理宏,如SIGNALSLOT进行连接)。

Qt 5.1 already provides its own implementation for making smart pointers for QSharedPointer . Qt 5.1已经提供了自己的实现,用于为QSharedPointer制作智能指针。

That static create member function can be used as follows: 静态create成员函数可以使用如下:

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

But note the description: 但请注意说明:

Note: This function is only available with a C++11 compiler that supports perfect forwarding of an arbitrary number of arguments. 注意:此函数仅适用于支持完全转发任意数量参数的C ++ 11编译器。 If the compiler does not support the necessary C++11 features, you must use the overload that calls the default constructor. 如果编译器不支持必要的C ++ 11功能,则必须使用调用默认构造函数的重载。

There are two major advantages of using make_shared and create functions rather than directly calling constructor with allocating memory with new : 使用make_sharedcreate函数有两个主要优点,而不是直接使用new分配内存来调用构造函数:

  1. That special perfectly forwarding function can allocate in a single system call a memory for both stored object and reference counter . 这种特殊的完美转发功能可以在单个系统中分配存储对象引用计数器的内存。

  2. The memory allocation is separated from the calling context, so you avoid memory leaks in case of an exception is thrown while constructing another object in eg a function call (where a compiler is free to choose the order in which arguments are evaluated). 内存分配与调用上下文分离,因此如果在例如函数调用中构造另一个对象时抛出异常,则可以避免内存泄漏(编译器可以自由选择评估参数的顺序)。 Consider: 考虑:

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

That is, if the compiler first executes the new QPushButton("Cancel", this) expression, and then calls the MayThrow() function before calling the constructor of QSharedPointer , you may leak memory if the MayThrow() function throws an exception. 也就是说,如果编译器将首先执行new QPushButton("Cancel", this)的表达,然后调用MayThrow()调用的构造函数之前功能QSharedPointer ,你可以,如果泄漏内存MayThrow()函数抛出异常。

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

相关问题 使用make_shared <std :: thread>创建shared_ptr <std :: thread>的实例 - Creating an instance of shared_ptr<std::thread> with make_shared<std::thread> make_shared创建std :: shared_ptr吗? gcc 4.6.2 - make_shared create std::shared_ptr? gcc 4.6.2 从std :: make_shared到std :: shared_ptr的分配静默失败? (VS2012错误) - Assignment from std::make_shared to std::shared_ptr fails silently? (VS2012 Bug) 的std :: shared_ptr的 <type> (new DerivedType(…))!= std :: make_shared <type> (DerivedType(...))? - std::shared_ptr<type>(new DerivedType(…)) != std::make_shared<type>(DerivedType(…))? std::shared_ptr 与 std::make_shared:意外缓存未命中和分支预测 - std::shared_ptr vs std::make_shared: unexpected cache misses and branch prediction 专攻std :: make_shared - Specializing std::make_shared std::make_shared 接口? - std::make_shared an interface? 尝试制作shared_ptr时std :: make_shared()中出现错误? - Errors in std::make_shared() when trying to make shared_ptr? std :: make_shared,std :: unique_ptr和移动构造函数 - std::make_shared, std::unique_ptr and move constructors std :: make_shared(),std :: weak_ptr和循环引用 - std::make_shared(), std::weak_ptr and cyclic references
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM