[C++] Costruttore di default

oleg.fresi
Buongiorno! Sto studiando l'ereditarietà in c++, e mi sono creato un esempio di codice per capre una cosa, ma ne ho scoperta un'altra che non conoscevo. Il codice è il seguente:
class A
{
public:
	int f()
	{
		cout << "ciao" << endl;
		return 9;
	}
};                                                      

class B : A
{
public:
	int a = f();
	
}; 

int main()
{
     B b1{};

    return 0;
}


Nel main creo un ogetto derivato di tipo $B$ derivato dalla classe $A$: Dunque dovrebbe essere eseguito il costruttore di default creato dal compilatore, come nel caso creassi un oggetto di tipo $A$, ma in questo caso viene stampato $"ciao"$, ovvero viene eseguita $f()$. Mi chiedo, come mai il costruttore di default della classe $B$ faccia questo quando in teoria non dovrebbe fare nulla.

Risposte
Super Squirrel
Ciao!
Semplicemente quando viene istanziato un oggetto della classe B viene eseguita la seguente istruzione:
int a = f();

Anche se a partire dal C++11 è permesso inizializzare un membro della classe alla sua dichiarazione, non è cmq una buona pratica di programmazione, meglio ricorrere al costruttore o ad una lista di inizializzazione.
Nel caso dai un'occhiata qui:
https://stackoverflow.com/questions/154 ... eclaration

oleg.fresi
Questa novità del c++11 mi sembra di averla già letta, ma ciò che non capisco è perchè viene eseguita quell'istruzione pur non essendo comandata? Oppure essendo l'unica, viene eseguita automaticamente dal costruttore?

apatriarca
L'espressione che fornisci come valore di default di una variabile membro viene sempre eseguita dal costruttore (di default o meno) ad eccezione che non venga fornita una inizializzazione diversa attraverso una initialization list.

oleg.fresi
Perfetto, ora è chiaro. Grazie tante a entrambi!

Super Squirrel
"apatriarca":
L'espressione che fornisci come valore di default di una variabile membro viene sempre eseguita dal costruttore (di default o meno) ad eccezione che non venga fornita una inizializzazione diversa attraverso una initialization list.

In pratica il "valore di default" agisce come una initialization list, ma ha una priorità inferiore. Nel senso che in caso di "valore di default" + initialization list + costruttore, la variabile membro non assume mai il valore di default, ma vengono "eseguiti" nell'ordine initialization list e costruttore. Giusto?

apatriarca
Esatto, ma non mi sono mai trovato in questa situazione devo dire.

Super Squirrel
Il seguente codice sembra confermarlo:
#include <iostream>

using namespace std;

int fun_1()
{
    cout << "fun_1";
    return 1;
}

int fun_2()
{
    cout << "fun_2";
    return 2;
}

class A
{
public:
    int n = fun_1();
    A():n(fun_2())
    {
        n = 3;
    }
};

int main()
{
    A a;
    cout << endl << a.n;
}

Output:
fun_2
3
Process returned 0 (0x0)   execution time : 0.021 s
Press any key to continue.

Qui un'ulteriore conferma:
https://stackoverflow.com/questions/403 ... onstructor

oleg.fresi
Chiarissimo, in effetti non dovrebbe capitare una situazione del genere, se non in qualche esercizio strano come il mio.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.