Qt smart peker - QSharedPointer

Qt Smart Pointer Qsharedpointer



Artikkel katalog

Forord

Qt-smartpekeren QSharedPointer har samme funksjon som std :: shared_ptr i C ++, og applikasjonsområdet er mer enn det vi sa før. QPointer med QScopedPointer Mer omfattende.

QSharedPointer

QSharedPointer er en delt peker som bryter det dynamiske objektet som er tildelt av den nye operatøren på bunken, akkurat som QScopedPointer, men den implementerer en referansetelling smart peker. Det vil si at, i motsetning til QScopedPointer, kan QSharedPointer fritt kopieres og tildeles verdier, deles hvor som helst, slik at QSharedPointer også kan brukes som et containerelement.



Den såkalte tellepekeren, det vil si den interne QSharedPointer refererer til minneressursene som eies av den interne QSharedPointeren. For eksempel, hvis 3 QSharedPointers peker på en minnressurs samtidig, så teller 3, vet at referansen teller til 0, og frigjør automatisk minnet. .



Merk at QSharedPointer er trådsikker, så det er ikke nødvendig å låse selv om det er flere tråder som endrer QSharedPointer-objektet samtidig. Selv om QSharedPointer er trådsikker, er det ikke sikkert at minneområdet som QSharedPointer peker på, er trådsikkert. Derfor bør flere tråder også vurdere å låse når du endrer dataene som QSharedPointer peker på.



La oss se på et offisielt eksempel:

static void doDeleteLater(MyObject *obj) { obj->deleteLater() } void otherFunction() { QSharedPointer obj = QSharedPointer(new MyObject, doDeleteLater) // continue using obj obj.clear() // calls obj->deleteLater() }

I dette eksemplet sendes en funksjon for tilpasset sletting.

Du kan også bruke medlemsfunksjoner direkte:



QSharedPointer obj = QSharedPointer(new MyObject, &QObject::deleteLater)

QSharedPointer er veldig praktisk å bruke, den brukes direkte på samme måte som vanlige pekere. Den kan brukes direkte etter opprettelsen, og den vil ikke bli brukt senere.

La oss se på et enkelt eksempel skrevet av meg selv:

class Student : public QObject { Q_OBJECT public: Student(QObject * parent = nullptr) ~Student() } class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0) ~Widget() private: QSharedPointer m_pStudent } #include 'widget.h' #include Widget::Widget(QWidget *parent) : QWidget(parent) { qDebug() << __FUNCTION__ m_pStudent = QSharedPointer(new Student()) } Widget::~Widget() { qDebug() << __FUNCTION__ } Student::Student(QObject *parent): QObject (parent) { qDebug() << __FUNCTION__ } Student::~Student() { qDebug() << __FUNCTION__ }

Lukk vinduet etter kjøring, skriv ut:

Widget Student ~Widget ~Student

Som du kan se, frigjøres studentobjektet automatisk.

Verdt å snakke om

Vi kjenner alle Qts QObject-objekttre-system (foreldre og barn). Hvis et overordnet objekt er spesifisert når objektet er opprettet, trenger ikke objektet å frigjøres manuelt, og det overordnede objektet vil gjøre ressursgjenvinning. Når jeg spør om smartpekerrelaterte data, ser jeg en artikkel som introduserer kombinasjonen av smartpeker og QObject-objekttreet-systemet, programmet vil krasje. Artikkelen er her Men dette er en blogg for seks år siden. Jeg prøvde det og resultatet viste ikke et krasj:

Fortsatt eksemplet ovenfor er endringene som følger:

m_pStudent = QSharedPointer(new Student(this))

Overordnet objekt er spesifisert når det er nytt

Det er normalt å lukke vinduet etter å ha kjørt. Jeg bruker Qt5.11.1

Forklar at Qt-oppdateringer i disse årene har løst dette problemet. Da kan vi bruke mindre forsiktighet i prosessen med å bruke, og bruke den med tillit.

OK, mer dokumentasjon, referanse Offisiell introduksjon