QScopedPointer
은 이동 의미 체계를 지원하지 않으므로 정확히 unique_ptr
보다 약합니다.
그 기능은 다른 점에서는 매우 유사합니다.
이동 의미는 매우 유용하며 실수로 잘못 사용하면 문제가 발생하는 경우는 거의 없습니다. 따라서 그들은 무해한 것에서부터 (더 일반적으로) 도움이되는 것까지 매우 그렇습니다.
QScopedPointer
을 사용해야하는 유일한 이유는 기존 코드 기반과의 상호 운용성입니다. 그리고 거기에서도, 그들이 얼마나 유사한 지 알면, 어댑터는 꽤 쉬울 것입니다.
적응할 필요가없는 경우 unique_ptr
을 사용하십시오.
이제는 적응에 대해 논의 할 것입니다.
까다로운 부분은 QScopedPointer
의 두 번째 매개 변수입니다. 매우 대략적으로 두 번째 매개 변수 unique_ptr
에 해당합니다.
unique_ptr
에는 상태 저장자가 허용됩니다. QScopedPointer
에서는 그렇지 않습니다.
static void cleanup(T* pointer)
꽤 일대일의 unique_ptr
에서
void operator()(T* pointer)const
에 해당합니다.따라서 :
template<class QDelete>
struct std_deleter {
template<class T>
void operator()(T* target) const {
QDelete::cleanup(target);
}
};
은 Qt deleter를 std deleter에 매핑합니다. 다른 방법은 비 저장되는 Deleter가에 의해 제한됩니다
template<class Std_deleter>
struct Qt_deleter {
template<class T>
static void cleanup(T* target) {
static_assert(std::is_empty<Std_deleter>{}, "Only works with stateless deleters");
Std_deleter{}(target);
}
};
우리가 지금 변환 할 수 있습니다
당신이
QScopedPointer
를 사용하는 거라고 유일한 이유에 대해 설명합니다
template<class T, class D>
QScopedPointer<T, Qt_deleter<D>>
to_qt(std::unique_ptr<T, D>&& src) {
return src.release();
}
template<class T, class D>
QScopedPointer<T, Qt_deleter<D>>
to_qt(std::unique_ptr<T[], D>&& src) {
return src.release();
}
template<class T>
QScopedPointer<T>
to_qt(std::unique_ptr<T>&& src) {
return src.release();
}
template<class T>
QScopedPointer<T, QScopedPointerArrayDeleter>
to_qt(std::unique_ptr<T[]>&& src) {
return src.release();
}
template<
class T, class D, class R=std::unique_ptr<T, std_deleter<D> >
>
to_std(QScopedPointer<T, D>&& src) {
return R(src.take()); // must be explicit
}
template<class T, class R=std::unique_ptr<T>>
to_std(QScopedPointer<T>&& src) {
return R(src.take()); // must be explicit
}
template<class T, class R=std::unique_ptr<T[]>>
to_std(QScopedPointer<T,QScopedPointerArrayDeleter >&& src) {
return R(src.take()); // must be explicit
}
. 몇 가지 경우가 있습니다. 기본 삭제 자 QScopedPointer
은 기본값 인 std::unique_ptr
으로 변환해야하며 반대의 경우도 마찬가지입니다.
어레이 삭제 QScopedPointer
은 unique_ptr<T[]>
으로, 그 반대로 변환되어야합니다.
다른 경우에는 단순히 Deleter를 마무리합니다. 이론 상으로는 정말 멋진 트릭은 들어오는 Deleter가 이미 포장되어 있고 포장을 뒤집어 썼는지를 알아 차리는 것이지만, 만약 당신의 코드가 많은 왕복을하고 있다면 아마도 이미 잘못된 것일 것입니다.
나는'std :: unique_ptr'을 사용할 것입니다. – NathanOliver
Qt 스마트 포인터의 사용량을 줄이고'std :: shared_ptr'과'std :: unique_ptr'을 사용하는 것으로 옮겼습니다. – drescherjm
표준 라이브러리와 다른 라이브러리 중 하나를 선택할 때마다 필자는 이유가없는 한 항상 표준 라이브러리를 선택합니다. 하나의 설득력있는 이유는 다른 유형을 사용하는 코드와의 상호 운용성이 필요한 경우입니다. –