programowanieProgramista C++

Jak działa konstruktor domyślny (default constructor) w C++? Co się stanie, jeśli nie zadeklarujesz żadnego konstruktora w klasie, oraz jeśli jawnie zadeklarujesz inne konstruktory, ale nie zadeklarujesz konstruktora domyślnego?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W C++ konstruktor domyślny to konstruktor bez parametrów lub z parametrami, z których wszystkie mają wartości domyślne. Jeśli w klasie nie zadeklarowano żadnego konstruktora, kompilator automatycznie wygeneruje publiczny konstruktor domyślny. Jednak jeśli zadeklarowano przynajmniej jeden inny konstruktor (na przykład konstruktor z parametrami), automatycznie dostarczony przez kompilator konstruktor domyślny już nie zostanie wygenerowany. Jeśli w takiej klasie potrzebny będzie także konstruktor domyślny, należy go jawnie zadeklarować (na przykład za pomocą ClassName() = default;).

Przykład kodu

class Foo { public: Foo(int x) {} // Konstruktor niestandardowy // Foo() domyślny już nie zostanie wygenerowany przez kompilator! }; Foo f; // Błąd kompilacji — brak konstruktora domyślnego!

Aby jawnie stworzyć konstruktor domyślny w takim przypadku, należy dodać:

class Foo { public: Foo() = default; Foo(int x) {} };

Pytanie z pułapką

„Jeśli masz tylko jeden konstruktor z parametrami, czy można tworzyć obiekty tej klasy bez parametrów? Dlaczego?”

Odpowiedź: Nie! Ponieważ, jeśli zadeklarowany jest jakikolwiek konstruktor, kompilator nie dodaje automatycznie konstruktora domyślnego. Aby tworzyć obiekty bez parametrów, należy jawnie dodać konstruktor domyślny do deklaracji.


Przykłady rzeczywistych błędów wynikających z nieznajomości niuansów tematu.


Historia

Na jednym dużym projekcie napisano hierarchię klas do serializacji danych, gdzie wszystkie "dziecięce" klasy miały tylko specyficzny konstruktor z parametrami. Po refaktoryzacji okazało się, że przy użyciu kontenerów STL (na przykład std::vector) z tymi klasami kompilacja zawodziła: kontener potrzebował konstruktora domyślnego, którego nie było. Problem został rozwiązany dopiero po jawnej deklaracji konstruktora domyślnego.


Historia

W projekcie wykorzystującym szablonowanie, jedna z klas-adapterów zadeklarowała tylko konstruktor z parametrami do przekazywania zasobów. Przy tym jedna z bibliotek wymagała istnienia konstruktora domyślnego dla poprawnego funkcjonowania (tworząc obiekty tymczasowe przez typy szablonów). Pojawiały się tajemnicze błędy linkowania, które długo nie mogły być wytłumaczone, aż do momentu wprowadzenia jawnego konstruktora domyślnego.


Historia

W kodzie zachodziła migracja z C++98 do C++11, i próba korzystania z "= default" do jawnego zadeklarowania konstruktora domyślnego. Na starych kompilatorach występowały błędy lub ignorowano nowe konstrukcje składniowe. To ujawniło, że nie wszyscy deweloperzy rozumieją różnicę między jawnie zaimplementowanym konstruktorem domyślnym, a tym generowanym przez kompilator oraz nową składnią "= default".