由于 Qt 使用其可怕的古老ptr机制,使用他们的QSharedPointer
大多不实用。
您在广告位中设置QSharedPointer
到nullptr
的那一刻很可能会导致未定义的行为(崩溃)。此外,与QSharedPointer
相比,std::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
虽然这似乎很有效,但我想知道是否还有其他陷阱,我没想过。也欢迎对此方法的评论。