Passando & # 8220; questo & # 8221; a una funzione all'interno di un costruttore?

StackOverflow https://stackoverflow.com/questions/445127

  •  22-07-2019
  •  | 
  •  

Domanda

Posso passare " questo " a una funzione come puntatore, all'interno del costruttore della classe, e utilizzarla per puntare ai membri dell'oggetto prima che il costruttore ritorni?

È sicuro farlo, purché i membri a cui si accede siano inizializzati correttamente prima della chiamata di funzione?

Ad esempio:

#include <iostream>

class Stuff
{
public:
    static void print_number(void *param)
    {
        std::cout << reinterpret_cast<Stuff*>(param)->number;
    }

    int number;

    Stuff(int number_)
        : number(number_)
    {
        print_number(this);
    }
};

void main() {
    Stuff stuff(12345);
}

Pensavo che non avrebbe funzionato, ma sembra. Questo comportamento standard o semplicemente un comportamento indefinito sta andando per la mia strada?

È stato utile?

Soluzione

Quando si crea un'istanza di un oggetto in C ++, il codice nel costruttore è l'ultima cosa eseguita. Tutte le altre inizializzazioni, inclusa l'inizializzazione della superclasse, l'esecuzione del costruttore della superclasse e l'allocazione della memoria avvengono in anticipo. Il codice nel costruttore è davvero solo per eseguire un'inizializzazione aggiuntiva una volta che l'oggetto è stato costruito. Quindi è perfettamente valido usare un "questo" puntatore nel costruttore di una classe e supponiamo che punti a un oggetto completamente costruito.

Ovviamente, devi ancora fare attenzione alle variabili membro non inizializzate, se non le hai già inizializzate nel tuo codice costruttore.

Altri suggerimenti

Puoi trovare una buona risposta a questo qui (FAQ C ++).

Si garantisce che tutti i membri ereditati e i membri della classe chiamante sono stati costruiti all'inizio dell'esecuzione del codice del costruttore e quindi possono essere referenziati in modo sicuro al suo interno.

Il gotcha principale è che non dovresti chiamare funzioni virtuali su this . La maggior parte delle volte che ci ho provato finisce per chiamare la funzione della classe base, ma credo che lo standard affermi che il risultato non è definito.

Come nota a margine sul codice presentato, vorrei invece modellare il void * :

class Stuff
{
public:
    template <typename T>
    static void print_number(const T& t)
    {
        std::cout << t.number;
    }

    int number;

    Stuff(int number_)
    : number(number_)
    {
        print_number(*this);
    }
};

Quindi visualizzerai un errore di compilazione se il tipo di t non ha un membro numero .

Andy, penso che ti sbagli sulla parte indefinita dello standard.

Quando sei nel costruttore, " questo " è un puntatore a un oggetto il cui tipo è la classe base dell'oggetto che si sta creando, il che significa che le funzioni virtuali parzialmente implementate nella classe base verranno chiamate e i puntatori nella tabella virtuale vinceranno " essere seguito.

Ulteriori informazioni nel C ++ Faq Lite ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top