V čem je lepší konstruktor? Ve všem :) Konstruktor slouží k počáteční inicializaci objektu. Pokud vytváříš objekt,
měl bys vždycky implementovat také vlastní konstruktor. Funkce Set() a pod. se používají na změnu hodnoty, ne k její inicializaci.
Inicializace probíhá při vytváření proměnné:
int a = 0; //je inicializce
int b;
b = 0; //není inicializace ale přiřazení
Pokud neimplementuješ konstruktor, bude program, kromě jiného, náchylný k chybám. Můžeš se pak dopustit například následující chyby:
Macka kocka;
int vek = kocka.GetVek(); //vrací hodnotu Vek objektu kocka, které není přiřazena žádná hodnota
Pokud však vytvoříš bezparametrický konstruktor, který proměnné Vek přiřadí hodnotu 0, předchozí příklad bude fungovat správně:
//konstruktor
Macka::Macka()
{
Vek = 0;
}
Dále si představ, že by třída Macka obsahovala také jméno kočky, které by bylo reprezentováno jako pole type char:
char *m_jmeno;
Třída by také pomocí metody SetJmeno umožňovala změnu jména. Implementace funkce by mohla vypadat následovně:
void Macka::SetJmeno(const char *jmeno)
{
delete [] m_jmeno;
m_jmeno = new char[strlen(jmeno) + 1];
strcpy(m_jmeno, jmeno);
}
Pokud bys nevytvořil vlastní konstruktor, následující program by vygeneroval chybu:
Macka liza;
liza.SetJmeno("liza"); //CHYBA
Mělo by to být jasné. Ukazatel m_jmeno obsahuje náhodnou hodnotu, protože nebyl při vytvoření objektu inicializován. Použití operátoru delete [] proto skončí chybou. Avšak použití operátoru delete na nulový ukazatel je zcela bezpečné.
Proto stačí vytvořit vlastní konstruktor, který inicializuje ukazatel na hodnotu NULL (popř. 0)
Macka::Macka()
{
Vek = 0;
m_jmeno = NULL;
}
Samozřejmě by bylo možné vytvořit "inicializační funkci", která by se starala o totéž jako konstruktor. Ale jaký by byl k tomu důvod, když se konstruktor volá automaticky, zatímco takovou funkci bychom museli volat explicitně?
Macka kocka;
kocka.Init(); //??? Jaký to má smysl ???