Często używamy struktur c ++ do definiowania struktury danych w przeciwieństwie do klasy, która może być kompletnym modułem z metodami składowymi. W głębi duszy wiemy, że oba są takie same (luźno mówiąc).
Fakt, że często używamy / traktujemy struktury jako jednostki tylko danych, powoduje, że nie dodajemy również domyślnych konstruktorów. Ale konstruktory są zawsze świetne, upraszczają i pomagają eliminować błędy.
Czy byłoby rozczarowanie, gdyby dodać domyślne konstruktory do moich struktur danych?
Czy implementacja domyślnego konstruktora powoduje, że struct Non-POD (zwykły stary typ danych), pod warunkiem spełnienia innych kryteriów?
Patrząc z perspektywy, rozważmy prosty przykład, ale w rzeczywistości struktura byłaby znacznie większa.
struct method
{
char name[32];
float temperature;
int duration;
};
Za każdym razem, gdy tworzę metodę, muszę się martwić (delikatnie mówiąc), czy zapomniałem ustawić jakąś wartość. Wyobraź sobie, że zapomniałem ustawić temperature
i zastosować metodę do systemu, który ma teraz losowo wysoką wartość i powoduje chaos. Lub zapomniałem ustawić, duration
a teraz metoda stosuje się przez nieznany długi czas.
Dlaczego powinienem brać odpowiedzialność za inicjalizację obiektu za każdym razem zamiast implementować jego konstruktor, który to gwarantuje?
struct
iclass
jest to, że domyślnie prywatny, a drugi do publicznej wiadomości.Odpowiedzi:
Czasami właściwe jest dodanie konstruktora do struktury, a czasem nie.
Dodanie konstruktora (dowolnego konstruktora) do struktury uniemożliwia użycie na nim inicjatora agregującego. Więc jeśli dodasz domyślny konstruktor, będziesz musiał również zdefiniować inny niż domyślny konstruktor inicjujący wartości. Ale jeśli chcesz mieć pewność, że zawsze inicjujesz wszystkich członków, jest to właściwe.
Dodanie konstruktora (ponownie dowolnego konstruktora) powoduje, że nie jest on POD, ale w C ++ 11 większość reguł, które wcześniej stosowano tylko do POD, zmieniono tak, aby dotyczyły standardowych obiektów układu, a dodawanie konstruktorów tego nie łamie. Tak więc inicjator agregacji jest w zasadzie jedyną rzeczą, którą tracisz. Ale często jest to również duża strata.
źródło
Z C ++ 11 możesz to zrobić
A gdy zapomnisz coś zainicjować, otrzymasz domyślną inicjalizację.
źródło
Szybka odpowiedź:
To zależy od tego, co chcesz osiągnąć.
Długa, rozszerzona, nudna odpowiedź:
Uderzyłeś w gwóźdź.
Zwykle nie podoba mi się, że „C ++” pozwala „Struct (s)” pozwala deklarować metody. Najlepiej używam wyraźnych „klas (y)” dla wymaganych metod i POD „struktur (y)” tylko dla pól.
Zgadzam się jednak, że niektóre podstawowe proste operacje, takie jak:
Są wymagane, a w tych okolicznościach metody konstrukcji mają sens.
Sugestia
Innym potencjalnym rozwiązaniem jest użycie struktur POD, ale nadal koncepcyjnie traktuj je jako klasy i obiekty.
Zawiń te deklaracje w przestrzeń nazw i dodaj funkcje globalne dla najważniejszych akcji.
Deklaracja kodu może być podobna do tej:
Kod, który stosuje rozwiązanie, może wyglądać mniej więcej tak:
To alternatywne podejście jest lepsze, gdy wymagany jest ogromny przydział pamięci danych lub interakcja z innymi bibliotekami współdzielonymi niskiego poziomu.
To podejście, z pewnymi zmianami, jest stosowane w rozwoju gier.
Dodatkowy
Osobiście uważam rozszerzenie składni dla „C ++”, a nawet nowe PL oparte na „C ++”, które rozwiązuje ten problem:
Twoje zdrowie.
źródło