由于Qt使用其可怕的古老 ptr 机制,因此使用它们QSharedPointer
大多是不切实际的。在插槽QSharedPointer
中设置 a的那一刻很可能会导致未定义的行为(崩溃)。此外,与相比, 的设计确实有错误的设计决策。所以我想到了一个合适的共享指针,它也可以在插槽中使用。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
虽然这似乎很有效,但我想知道是否还有其他陷阱,我没有考虑过。也将不胜感激有关这种方法的评论。