Konstruktory są prawdopodobnie złą nazwą. Jest to praktycznie inicjator dla wstępnie skonstruowanych obiektów. Najprostszym sposobem zilustrowania tego jest pseudo-przykład dla równoważnej konstrukcji bez użycia konstruktorów C++.
Z konstruktorów
struct X {
int a;
X() {
a = -5;
}
};
int main() {
X* x1 = new X(); // X created as a "reference object".
X x2; // X created as a "value object" on the stack.
return x1->a - x2.a;
}
Bez konstruktorów
struct X {
int a;
void initialize() {
a = -5;
}
static X* create() {
X* res = (X*)malloc(sizeof(X));
res->initialize();
return res;
}
};
int main() {
X* x1 = X::create(); // New constructed heap-allocated X
X x2; // Stack-allocated X
x2.initialize(); // Manually initialized
return x1->a - x2.a;
}
Teraz, jeśli sobie wyobrazić, że X::initialize
w drugim przykładzie miały zostać wykonane, aby wrócić, powiedzmy bool
wskazując sukces lub niepowodzenie, byś mieć problem. W wersji main()
nieuważny programator może zakończyć się niepowodzeniem, ponieważ nie został poprawnie zainicjowany, co prowadzi do niezdefiniowanego zachowania (zwykle jest to trudna do debugowania awaria, która może nie zostać wykryta przed rozpoczęciem produkcji).
Jest to jeden z głównych powodów, dla których konstruktorzy są wyjątkowi. Jedynymi dwoma sposobami wyjścia z konstruktora są normalne zakończenie lub wyjątek, który następnie musi być obsługiwany przez wywołującego (lub przekazywany na stos). W każdym razie uniemożliwiasz zakończenie niezainicjowanych obiektów.
Na marginesie niezainicjowane obiekty są jedną z najczęstszych przyczyn błędów w C, która nie ma nic, co mogłoby pomóc programistom w ten sposób.
Z ciekawości, kiedy byłoby użyteczne, a nawet ma sens, aby konstruktor zwrócił coś innego niż obiekt, który konstruuje? – kevin628
AFAIK zwraca nowo utworzony obiekt. –
Kto powiedział, że konstruktor jest funkcją? (Oprócz faktu, że jest to opisane w sekcji Standard o "Special Member Functions") –