C++/Konstruktor i destruktor: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
+delegacja konstruktorów
+konstruktory explicit
Linia 219:
};
</source>
 
 
===Konstruktor explicit - zabronienie niejawnych konwersji (C++)===
 
Czasem niepożądane jest, żeby można było "przez przypadek" utworzyć klasę bądź przypisać do niej wartość. Jeśli klasa posiada konstruktor konwertujący, to kompilator jest w stanie wydedukować sposób na przekształcenie jednego typu w drugi, tj. dokonać '''niejawnej konwersji'''. Takie zachowanie nie zawsze jest pożądane i w dużych systemach jest dość trudne do przewidzenia i rozpoznania przez programistę.
 
Zobaczmy na przykład:
 
<source lang="cpp" highlight="10">
class Klasa {
public:
Klasa(int x) {}
};
 
int main() {
 
Klasa k(42);
 
k = -1;
}
</source>
 
Ostatnie przypisanie choć wygląda dziwnie, nie jest błędem. Kompilator widzi, że z typu <tt>int</tt> może utworzyć Klasę, a także dla Klasy istnieje domyślny operator przypisania, więc ostatnia linijka zostanie zainterpretowana jako:
 
<source lang="cpp">
k.operator=(Klasa(-1));
</source>
 
Do rozwiązania tego typu problemów w C++11 wprowadzono nowy klasyfikator dla konstruktorów '''explicit'''. Jeśli istnieje konstruktor z '''explicit''' wówczas utworzenie klasy, która byłaby wynikiem konwersji niejawnej stanie się niemożliwe.
 
<source lang="cpp" highlight="3">
class Klasa {
public:
explicit Klasa(int x) {}
};
 
int main() {
 
Klasa k(42);
 
// k = -1; // błąd: kompilator nie wie jak skonwertować int na Klasa
}
</source>
 
Dopiero wprowadzenie '''jawnej konwersji''' operatorem '''static_cast''' umożliwia zastosowania konstruktora konwertującego. Taki operator jest dobrze widoczny w kodzie źródłowym i jasno oddaje intencje użycia:
 
<source lang="cpp">
k = static_cast<Klasa>(-1);
</source>