Puntatori intelligenti in C++
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 15 di 104.
Gli smart pointer sono classi wrapper che gestiscono automaticamente la memoria heap per te. Eliminano la necessità di chiamate manuali a delete, liberando la memoria quando il puntatore esce dall'ambito.
Includi l'header <memory> per usare i puntatori intelligenti.
unique_ptr - proprietà esclusiva. Solo un puntatore alla volta può possedere la risorsa.
#include <memory>
std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack(); // Usa come un normale puntatore
// Non si può copiare, ma si può trasferire la proprietà
std::unique_ptr<Player> player2 = std::move(player);
// player ora è nullptrshared_ptr - proprietà condivisa. Più puntatori possono possedere la stessa risorsa. La memoria viene liberata quando l'ultimo proprietario viene distrutto.
std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1; // Both own the resource
std::cout << p1.use_count(); // Prints 2weak_ptr - osservatore non proprietario di un shared_ptr. Utile per interrompere i riferimenti circolari.
std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;
if (auto locked = weak.lock()) { // Converti in shared_ptr
locked->attack();
}Usa unique_ptr per impostazione predefinita per la proprietà esclusiva. Usa shared_ptr quando più oggetti devono condividere una risorsa. Usa weak_ptr per osservare senza prolungare la durata.
Preferisci make_unique e make_shared a new senza wrapper.
Sfida
FacileCreiamo un sistema di condivisione di documenti che dimostri i diversi modelli di proprietà dei puntatori intelligenti. Vedrai come unique_ptr impone la proprietà esclusiva, come shared_ptr consente più proprietari e come weak_ptr può osservare senza influire sul ciclo di vita.
Creerai due file per organizzare il codice:
Document.h: definisci una classeDocumentche rappresenta un documento condivisibile. Dovrebbe avere:- Un attributo privato
title(stringa) - Un costruttore che accetta un titolo e stampa
"Document created: <title>" - Un distruttore che stampa
"Document deleted: <title>" - Un metodo
getTitle()che restituisce il titolo
- Un attributo privato
main.cpp: dimostra tutti e tre i tipi di puntatori intelligenti leggendo un titolo di documento dall'input, quindi:- Crea un
unique_ptra un Document con il titolo inserito - Stampa
"Unique owner: <title>" - Trasferisci la proprietà a un altro
unique_ptrusandostd::move - Stampa
"Ownership transferred" - Crea un
shared_ptra un nuovo Document con il titolo"SharedDoc" - Crea un secondo
shared_ptrche punta allo stesso documento - Stampa
"Shared owners: <count>"usandouse_count() - Crea un
weak_ptrda uno dei puntatori condivisi - Usa
lock()per accedere al documento tramite il puntatore debole e stampa"Weak access: <title>"
- Crea un
Ricorda di includere <memory> per i puntatori intelligenti. Usa std::make_unique e std::make_shared per creare i puntatori intelligenti. I messaggi del distruttore ti aiuteranno a vedere quando ciascun documento viene eliminato automaticamente al termine del programma.
Includi il file header in main.cpp usando #include "Document.h".
Provalo tu
#include <iostream>
#include <memory>
#include <string>
#include "Document.h"
using namespace std;
int main() {
string inputTitle;
cin >> inputTitle;
// TODO: Crea un unique_ptr a un Document con inputTitle
// usando std::make_unique
// TODO: Imprime "Unique owner: <title>"
// TODO: Transfiere la propiedad a otro unique_ptr usando std::move
// TODO: Imprime "Ownership transferred"
// TODO: Crea un shared_ptr a un nuevo Document con el título "SharedDoc"
// usando std::make_shared
// TODO: Crea un segundo shared_ptr que apunte al mismo documento
// TODO: Imprime "Shared owners: <count>" usando use_count()
// TODO: Crea un weak_ptr a partir de uno de los punteros compartidos
// TODO: Usa lock() para acceder al documento mediante weak_ptr
// e imprime "Weak access: <title>"
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online