C++ Academy · Oppitunti

Näkyvyysalueen vartijat

Suorita siivous näkyvyysalueelta poistuttaessa

Oppitunti 4/413 vaihetta

Näkyvyysalueen vartijat on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu C++ Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Mikä on scope guard?

Scope guard on RAII-objekti, jonka ainoa tehtävä on suorittaa siivoustoiminto näkyvyysalueelta poistuttaessa — myös aikaisen paluun tai poikkeuksen yhteydessä.

Ratkaistava ongelma

Ilman scope guardia aikaisen return-paluun tai throw-lauseen jälkeinen siivous unohtuu helposti. Scope guard tekee toiminnosta automaattisen.

lock_guard: standardikirjaston scope guard

std::lock_guard lukitsee mutexin konstruktion yhteydessä ja vapauttaa lukituksen tuhoamisen yhteydessä — se on sisäänrakennettu scope guard lukituksia varten.

#include <mutex>

std::mutex m;

void critical() {
    std::lock_guard<std::mutex> lk(m);   // locked
    // ... work ...
}                                        // unlocked automatically

Itse kirjoitettu scope guard

Voitte kirjoittaa scope guardin, joka säilyttää funktion ja kutsuu sitä destruktorissa.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "cleanup\n"; });
    std::cout << "work\n";
}

Siivous suoritetaan aikaisen paluun yhteydessä

Koska destruktori suoritetaan näkyvyysalueelta poistuttaessa, scope guardin toiminto suoritetaan riippumatta siitä, miten funktio päättyy.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

void run(bool stop) {
    ScopeGuard g([] { std::cout << "always cleaned\n"; });
    if (stop) return;
}

int main() { run(true); }

Siivous suoritetaan poikkeuksen yhteydessä

Jos poikkeus purkaa näkyvyysalueen, scope guardin destruktori suoritetaan silti ja vapauttaa resurssin turvallisesti.

Scope guardin peruuttaminen

Joskus siivous halutaan ohittaa, kun toiminto onnistuu. Oikeissa scope guard -toteutuksissa on tätä varten dismiss(), joka poistaa toiminnon käytöstä.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
    bool active = true;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    void dismiss() { active = false; }
    ~ScopeGuard() { if (active) fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "rollback\n"; });
    g.dismiss();   // success: no rollback
}

Käyttäkää palautukseen

Scope guardit ovat parhaimmillaan transaktionaalisessa koodissa: rekisteröikää palautustoiminto, suorittakaa työ ja poistakaa scope guard käytöstä onnistumisen jälkeen.

Scope guardit ovat vain siirrettäviä

Scope guardia ei pitäisi kopioida — kopiointi suorittaisi toiminnon kahdesti. Tehkää scope gardeista vain siirrettäviä tai ei-kopioitavia.

Standardikirjaston apuvälineet

std::scoped_lock suojaa useita mutexeja, ja GSL:n kaltaiset kirjastot tarjoavat finally-toiminnon. Monissa koodikannoissa on pieni ScopeGuard-apuohjelma.

Suosikaa erityisiä RAII-tyyppejä

Kun käytettävissä on tarkoitukseen tehty RAII-tyyppi (lock_guard, unique_ptr, fstream), suosikaa sitä. Käyttäkää yleistä scope guardia vain tapauskohtaiseen siivoukseen, jolle ei ole luontevaa kääretyyppiä.

Pikatarkistus

Testatkaa, miten hyvin ymmärrätte scope guardit.

Kertaus

Opitte, että scope guard suorittaa siivouksen automaattisesti näkyvyysalueelta poistuttaessa RAII:n avulla. Se käsittelee aikaiset paluut ja poikkeukset, tukee palautusta dismiss()-toiminnolla ja sen pitäisi olla vain siirrettävä. Suosikaa tarkoitukseen tehtyjä RAII-tyyppejä aina, kun niitä on saatavilla.

Aloita maksutta

Opi C++ tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
51
Oppitunnit
203

Usein kysytyt kysymykset

Onko oppitunti ”Näkyvyysalueen vartijat” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “Näkyvyysalueen vartijat”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Näkyvyysalueen vartijat”?

Suorita siivous näkyvyysalueelta poistuttaessa Harjoittelet C++ Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C++ Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C++ Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Näkyvyysalueen vartijat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C++ Academy-oppitunnilla?

Kyllä. Jokainen C++ Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. RAII-periaate
  2. Destruktorit ja siivous
  3. Kolmen/viiden sääntö
  4. Näkyvyysalueen vartijat
← Takaisin: C++ Academy