Qt 智能指針QScopedPoint用法小結
1. 智能指針是什么
智能指針是C++11引入的一種指針封裝類型,用于自動管理動態(tài)分配的內(nèi)存。智能指針的目的是解決傳統(tǒng)裸指針帶來的內(nèi)存泄漏、懸掛指針等問題,并使代碼更安全、更易讀。
2. 智能指針有什么用
1.自動管理內(nèi)存,避免內(nèi)存泄漏和懸掛指針問題;
2.簡化代碼,減少異常處理和資源管理的復雜性;
3.提高代碼可讀性和可維護性;
4.幫助實現(xiàn)RAII(資源獲取即初始化)原則,更好地管理資源。
3. 智能指針和普通指針區(qū)別
智能指針和普通指針的主要區(qū)別在于內(nèi)存管理方式。普通指針(裸指針)直接使用內(nèi)存地址,需要手動申請和釋放內(nèi)存,容易導致內(nèi)存泄漏和懸掛指針等問題。而智能指針封裝了內(nèi)存地址,通過自動管理內(nèi)存的方式避免了這些問題。
智能指針內(nèi)部維護了一個引用計數(shù)器,當一個智能指針被創(chuàng)建或拷貝時,計數(shù)器加1;當一個智能指針被銷毀或重置時,計數(shù)器減1。當計數(shù)器減至0時,智能指針會自動釋放其所指向的內(nèi)存。這種方式稱為“所有權”(ownership)模型,智能指針具有其內(nèi)存的所有權,避免了普通指針中的多個指針指向同一內(nèi)存地址的情況。
另外,智能指針還提供了一些有用的成員函數(shù),如reset()、release()等,可以更方便地進行內(nèi)存管理。同時,智能指針的類型也不同,如std::unique_ptr表示獨占所有權的智能指針,std::shared_ptr表示共享所有權的智能指針,std::weak_ptr表示觀察智能指針等。
4. QScopedPoint介紹
QScopedPointer類用于存儲一個指向動態(tài)分配的對象的指針,并在對象銷毀時自動刪除它。
手動管理堆分配的對象是困難且容易出錯的。常見的后果是代碼內(nèi)存泄漏,難以維護。QScopedPointer是一個小工具類,通過將基于堆棧的內(nèi)存所有權分配給堆分配,一般稱資源獲取即初始化(RAII),從而大大簡化了這一點。
QScopedPointer保證當當前作用域消失時,所指向的對象將被刪除。
當使用QScopedPointer時,可以確保在函數(shù)退出時,所分配的對象會被自動刪除,從而避免了內(nèi)存泄漏。這使得代碼更簡潔、更安全,減少了內(nèi)存泄漏和代碼錯誤的風險。
比如:一般我們自行new在堆中創(chuàng)建對象時,需手動管理內(nèi)存,如下:
void myFunction(bool useSubClass)
{
MyClass *p = useSubClass ? new MyClass() : new MySubClass;
QIODevice *device = handsOverOwnership();
if (m_value > 3) {
delete p;
delete device;
return;
}
try {
process(device);
}
catch (...) {
delete p;
delete device;
throw;
}
delete p;
delete device;
}如果改用智能指針,代碼清晰易懂
void myFunction(bool useSubClass)
{
// assuming that MyClass has a virtual destructor
QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass);
QScopedPointer<QIODevice> device(handsOverOwnership());
if (m_value > 3)
return;
process(device);
}如果被const修飾,普通指針與智能指針的對比:
const QWidget *const p = new QWidget();
// 等同于
const QScopedPointer<const QWidget> p(new QWidget());
QWidget *const p = new QWidget();
// 等同于
const QScopedPointer<QWidget> p(new QWidget());
const QWidget *p = new QWidget();
// 等同于
QScopedPointer<const QWidget> p(new QWidget());5. QScopedPoint用法
首先包含頭文件
#include <QScopedPointer>
QScopedPointer<int> pInt(new int(99));
qDebug().noquote() << "*pInt :" << *pInt << *pInt.data(); // 99 99使用很簡單。
6. take()和data()方法區(qū)別
QScopedPointer 有兩個重要的方法:take() 和 data()。
take() 方法:
- take() 是一個成員函數(shù),它允許你獲取 QScopedPointer 所指向的對象,并將 QScopedPointer 設置為 null。這意味著一旦調(diào)用了 take(),QScopedPointer 將不再擁有該對象,并且不再負責其生命周期。
- 這個方法通常用于在多線程環(huán)境中安全地傳遞對象,或者在知道對象生命周期的情況下安全地獲取對象。
data() 方法:
- data() 返回一個指向所持有對象的指針。這個方法主要用于訪問或修改所指向的對象。
- 注意,盡管 data() 返回一個指針,但這個指針的生命周期依賴于 QScopedPointer 的生命周期。如果 QScopedPointer 被銷毀,那么這個指針將變得無效。
使用注意事項:
- 使用 take() 時要特別小心,確保在 take() 之后,不會意外地使用 QScopedPointer,因為這樣可能會導致未定義的行為。
- 使用 data() 時,要確保在 QScopedPointer 的生命周期內(nèi)使用返回的指針,否則可能會導致懸掛指針或其他問題。
#include <QScopedPointer>
class MyClass {
public:
MyClass() {
// 初始化操作
}
~MyClass() {
// 清理操作
}
void show() {
// 顯示對象內(nèi)容
}
};
int main() {
QScopedPointer<MyClass> ptr(new MyClass); // 創(chuàng)建一個 MyClass 對象,QScopedPointer 管理其生命周期
// 使用 data() 方法訪問對象
MyClass* rawPtr = ptr.data(); // 返回原始指針,QScopedPointer 仍然擁有這個對象
rawPtr->show(); // 顯示對象內(nèi)容
// 使用 take() 方法轉(zhuǎn)移對象所有權
MyClass* takenPtr = ptr.take(); // take() 返回原始指針,QScopedPointer 不再擁有這個對象
takenPtr->show(); // 顯示對象內(nèi)容,然后釋放 takenPtr,不調(diào)用 MyClass 的析構函數(shù)
return 0;
}如下示例:
#include <QScopedPointer>
class MyClass {
public:
MyClass() {
// 初始化操作
}
~MyClass() {
// 清理操作
}
void show() {
// 顯示對象內(nèi)容
}
};
int main() {
QScopedPointer<MyClass> ptr(new MyClass); // 創(chuàng)建一個 MyClass 對象,QScopedPointer 管理其生命周期
// 使用 data() 方法訪問對象
MyClass* rawPtr = ptr.data(); // 返回原始指針,QScopedPointer 仍然擁有這個對象
rawPtr->show(); // 顯示對象內(nèi)容
// 使用 take() 方法轉(zhuǎn)移對象所有權
MyClass* takenPtr = ptr.take(); // take() 返回原始指針,QScopedPointer 不再擁有這個對象
takenPtr->show(); // 顯示對象內(nèi)容,然后釋放 takenPtr,不調(diào)用 MyClass 的析構函數(shù)
return 0;
}到此這篇關于Qt 智能指針QScopedPoint用法小結的文章就介紹到這了,更多相關Qt 智能指針QScopedPoint內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

