0

由于Qt使用其可怕的古老 ptr 机制,因此使用它们QSharedPointer大多是不切实际的。在插槽QSharedPointer中设置 a的那一刻很可能会导致未定义的行为(崩溃)。此外,与相比, 的设计确实有错误的设计决策。所以我想到了一个合适的共享指针,它也可以在插槽中使用。nullptrQSharedPointerstd::shared_ptr

我想出的是以下内容:

template <typename T>
struct LateDeleter {
    void operator()( T* ptr ) {
        if( !ptr )
            return;
        auto qObject = static_cast<QObject*>( ptr );
        qObject->deleteLater();
    }
};

template <typename T>
class QSharedPtr : public std::shared_ptr<T> {
public:
    typedef std::shared_ptr<T> __base;
#ifdef Q_OS_WIN
    QSharedPtr() : __base( nullptr, LateDeleter<T>() ) {}
#else
    constexpr QSharedPtr() : __base( nullptr, LateDeleter<T>() ) {}
#endif
    template< class Y >
    explicit QSharedPtr( Y* ptr ) : __base( ptr, LateDeleter<T>() ) {}
#ifdef Q_OS_WIN
    QSharedPtr( std::nullptr_t ) : __base( nullptr, LateDeleter<T>() ) {}
#else
    constexpr QSharedPtr( std::nullptr_t ) : __base( nullptr, LateDeleter<T>() ) {}
#endif
    template< class Y >
    QSharedPtr( const QSharedPtr<Y>& r ) : __base( r ) {}
    QSharedPtr( QSharedPtr&& r ) : __base( std::forward<QSharedPtr>(r) ) {}
    template< class Y >
    QSharedPtr( QSharedPtr<Y>&& r ) : __base( std::forward<QSharedPtr<Y>>(r) ) {}
};

#ifdef Q_OS_WIN
// Hacky solution for VS2010
template<class _Ty, class T1>
QSharedPtr<_Ty> makeShared( T1&& arg1 ) {   // make a shared_ptr
    auto ptr = new _Ty( std::forward<T1>(arg1) );
    return QSharedPtr<_Ty>( ptr );
}
#else
// Use proper variadic template arguments
template <class T, class... Args>
QSharedPtr<T> makeShared( Args&&... args ) {
    auto ptr = new T( std::forward<Args>(args)... );
    return QSharedPtr<T>( ptr );
}
#endif

虽然这似乎很有效,但我想知道是否还有其他陷阱,我没有考虑过。也将不胜感激有关这种方法的评论。

4

0 回答 0