Re: [C++] distruttori e memoria stack

Messaggioda apatriarca » 04/02/2020, 21:03

Ti consiglio di fare esperimenti, ma il risultato in quel caso sarebbe:
Codice:
Create A
Create A
Create A
Destroy A
Destroy A

Hai insomma eliminato la creazione e distruzione dell'oggetto third ottenendo 3 chiamate al construttore e due al distruttore (e nessuna al costruttore di copia che veniva usato per third).

Se allochi della memoria in una funzione che deve essere deallocata al di fuori di essa hai le seguenti opzioni:
1. Restituire un puntatore a tale memoria. Il codice che fa uso della funzione si deve ricordare di deallocare tale memoria.
2. Restituire la memoria usando uno smart pointer (shared_ptr o unique_ptr).

In linea di massima, quando si ha a che fare con un container di qualche tipo è difficile che uno si metta a definire una funzione come operator- a meno di copiare il container (eventualmente usando la move semantic). L'alternativa più comune è quella di richiedere il passaggio (per riferimento) di un container o un iteratore da usare come output. A tale proposito considera la funzione set_difference in algorithm. L'output è scritto su un output iterator (un iteratore che permette la scrittura nella posizione corrente e l'incremento).
apatriarca
Moderatore
Moderatore
 
Messaggio: 5359 di 5389
Iscritto il: 08/12/2008, 20:37
Località: Londra

Re: [C++] distruttori e memoria stack

Messaggioda anto_zoolander » 04/02/2020, 21:24

Grazie per i consigli.

Ci tengo molto ad imparare bene questo linguaggio, mi piace molto.
In effetti ne faccio molti di esperimenti ma poi finisco per impelagarmi in qualche groviglio :lol:

ho compilato questo:

Codice:
#include <iostream>

int& f(void) {
    int* x = new int{};
    std::cout<<"indirizzo nella funzione= "<<x<<std::endl;
   
    return *x;
}

int main(void) {
   
    int& y{f()};
    std::cout<<"indirizzo fuori funzione= "<<&y<<std::endl;
   
}

Ottengo che la variabile $y$ assume "l'identità" di x
Mentre se tolgo il riferimento da $y$ no.

che penso sarebbe la stessa cosa di tornare un puntatore.
A questo punto mi viene spontanea una domanda: le funzioni che ritornano un riferimento ha senso usarle, in un constesto di inizializzazione/assegnazione, solo per variabili reference?

PS: mi sono iscritto su Codility, grazie per avermelo segnalato :-D
Error 404
Avatar utente
anto_zoolander
Moderatore
Moderatore
 
Messaggio: 4339 di 4389
Iscritto il: 06/10/2014, 15:07
Località: Palermo

Re: [C++] distruttori e memoria stack

Messaggioda apatriarca » 04/02/2020, 22:23

È certamente possibile scrivere
Codice:
delete &y;

dove y è un riferimento ad un blocco di memoria allocato dinamicamente. Tuttavia si da normalmente per scontato che la memoria puntata da un riferimento sia gestita da qualcun altro e che la vita della memoria è più grande della vita del riferimento.

Una funzione che restituisce un reference ha senso in questi casi:
1. Stai restituendo *this da una variabile membro di una funzione. È questo per esempio il caso degli operatori di assegnamento.
2. Restituisci il riferimento ad una variabile globale o una variabile statica in una classe o funzione.

Non è comunque difficile pensare ad esercizi che puoi fare. Per esempio puoi provare a scrivere un programma che
1. legge una espressione e ne calcola il risultato. O che ne calcola la derivata o altro. Una specie di calcolatrice insomma o un linguaggio di programmazione semplificato.
2. copia il comportamento di qualche utility linux (grep per esempio)
3. implementa un qualche gioco di carte o scacchi/dama..
4. implementa una semplice chat
5. implementa un ray tracer
apatriarca
Moderatore
Moderatore
 
Messaggio: 5361 di 5389
Iscritto il: 08/12/2008, 20:37
Località: Londra

Re: [C++] distruttori e memoria stack

Messaggioda Super Squirrel » 05/02/2020, 01:23

In generale una funzione che ritorna un riferimento può essere anche utilizzata come l-value.
E' un esempio stupido, ma è la prima cosa che mi è venuta in mente:
Codice:
#include <iostream>

using namespace std;

int& massimo(int* v, const unsigned int dim)
{
    unsigned int i = 0;
    for(unsigned int j = 1; j < dim; ++j)
    {
        if(v[j] > v[i])
        {
            i = j;
        }
    }
    return v[i];
}

int main()
{
    const unsigned int dim = 7;
    int v[dim] = {4, 5, 3, 1, -6, 8, -2};
    massimo(v, dim) = 0;
    for(unsigned int i = 0; i < dim; ++i)
    {
        cout << v[i] << " ";
    }
}


Se ti può essere utile butto lì alcune idee basate su programmi che ho realizzato in passato: una classe per la gestione dei numeri razionali o del calcolo matriciale, gioco della scopa, risolutore di sudoku (magari basato anche su strategie logiche e non solo sulla forza bruta), tetris, ...
Super Squirrel
Junior Member
Junior Member
 
Messaggio: 384 di 392
Iscritto il: 16/05/2013, 22:05

Precedente

Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti