![](/img/trans.png)
[英]Creating an instance of shared_ptr<std::thread> with make_shared<std::thread>
[英]Qt::make_shared for creating QSharedPtr as std::make_shared for creating std::shared_ptr
正如Bjarne Stroustrup的“C ++之旅”中所述,並且作為已知的C ++ 14實踐,應該避免在代碼中使用裸new
和delete
。 標准庫提供了std::make_shared
和std::make_unique
用於創建智能指針以立即存儲已分配的對象。
但是,不可能將這些例程用於非標准智能指針,例如Qt。 Qt有自己的內存管理模型(帶父QSharedPointer
),但也提供了QSharedPointer
和QPointer
等智能指針類(盡管后者實際上並不是擁有指針)。
我的問題是:創建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
QPointer
有用,因為它會隱藏new
運算符並確保只為繼承QObject
東西調用new
。 Qt用戶做了很多new
的,但是通過這種方式我們可以確定new
只在Qt上下文中使用。 關於這個想法的任何爭論?
諸如make_shared
嚴格依賴於完美的轉發功能,該功能僅在C ++ 11和引入通用(轉發)引用時可用。 話雖如此,如果沒有完美的轉發 ,使用此功能可能效率低下。 Qt比最近的C ++標准要老,因此直到Qt 5.1才能使用它(就像之前你必須使用Qt的內部預處理宏,如SIGNAL
和SLOT
進行連接)。
Qt 5.1已經提供了自己的實現,用於為QSharedPointer制作智能指針。
靜態create
成員函數可以使用如下:
auto ptr = QSharedPointer<QPushButton>::create("Cancel", this);
但請注意說明:
注意:此函數僅適用於支持完全轉發任意數量參數的C ++ 11編譯器。 如果編譯器不支持必要的C ++ 11功能,則必須使用調用默認構造函數的重載。
使用make_shared
和create
函數有兩個主要優點,而不是直接使用new
分配內存來調用構造函數:
這種特殊的完美轉發功能可以在單個系統中分配存儲對象和引用計數器的內存。
內存分配與調用上下文分離,因此如果在例如函數調用中構造另一個對象時拋出異常,則可以避免內存泄漏(編譯器可以自由選擇評估參數的順序)。 考慮:
foo(QSharedPointer<QPushButton>(new QPushButton("Cancel", this)), MayThrow());
也就是說,如果編譯器將首先執行new QPushButton("Cancel", this)
的表達,然后調用MayThrow()
調用的構造函數之前功能QSharedPointer
,你可以,如果泄漏內存MayThrow()
函數拋出異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.