Konstruktor domyślny na liście inicjalizacyjnej

0

Witam
Stworzyłem sobie klasę zawierającą składowe stałe. Np. taką:

class Mapa {
private:
  float const evaporate_rate;
  float const alpha;
  float const beta;
  int size;
  /*...*/
}

Do ich zainicjalizowania potrzebuję listy inicjalizacyjnej. Chcę mieć możliwość tworzenia obiektów tej klasy na kilka sposobów, wliczając w to m.in. domyślne wartości dla w/w składników.

Moje pytanie: Na ile poprawne i zgodne z zasadami jest wykorzystanie w tym przypadku prywatnego konstruktora domyślnego posiadającego listę inicjalizacyjną z tymi wartościami:

Mapa::Mapa() : evaporate_rate(0.95), alpha(2), beta(1.5) {/*...*/}

a do tworzenia innych wystąpień tej klasy używanie np. takich konstruktorów (ze szczególnym uwzględnieniem poprawności konstruktora domyślnego tej samej klasy na liście):

Mapa::Mapa(int size) : Mapa() {/*...*/}
Mapa::Mapa(float eva, float ala, float beata, int size) : evaporate_rate(eva), alpha(ala), beta(beata) {/*...*/}

Czy takie podejście nie wpłynie jakoś negatywnie/niespodziewanie na działanie i wydajność programu (wycieki pamięci itp ;))?

1

rozwiazanie jest ok jezeli jestes pewien ze chcesz miec konstruktor domysly jako prywatny (w sensie obiekt musi byc tworzony z jakims parametrem zawsze).
jedynie opisalbym co te magiczne numerki znacza (0.95) (2) etc...

1

Twoim kodzie nie ma nic związanego z zarządzeniem pamięci, wiec nie może być problemu z wyciekiem.
Prywatny konstruktor domyślny jest w tym przypadku bezsensu, jeśli już go potrzebujesz to uczyń go publicznym.

0
MarekR22 napisał(a):

Prywatny konstruktor domyślny jest w tym przypadku bezsensu, jeśli już go potrzebujesz to uczyń go publicznym.

Prywatny jest dlatego, żeby nie używać go do tworzenia obiektów z zainicjalizowanymi tylko składowymi stałymi (takiego półproduktu).
Może nie zaznaczyłem tego wyraźnie (z myślą o nie zaciemnianiu istoty mojego pytania) ale klasa ta będzie bardziej rozbudowana i jej funkcjonalność nie będzie ograniczać się jedynie do przechowywania zmiennych/stałych.
A wtrącenie o wycieku wynikło z przemyśleń, na ile mogę wykorzystać ten konstruktor do jeszcze innych celów i jak wygląda w tym przypadku "ścieżka budowy" obiektów (czy nie powstanie mi gdzieś obiekt bez dowiązania).

1

konstruktor domyslny prywatny jest bezsensu w tym wypadku bo dajesz mozliwosc zainicjalizowania tamtych pol. Wiec rownie dobrze, moge je zainicjalizowac wartosciami domyslnymi... ale zamiast po prostu stworzyc obiekt musze zrobic to zrobic reczne (wpisac te 4 argumenty) co jest bez sensu.

jezeli nie dawalbys dostepu do tych danych (tylko mialbys Mapa::Mapa(int size) : Mapa() {/.../}) to wtedy jak najbardziej ma sens ;)

0
fasadin napisał(a):

konstruktor domyslny prywatny jest bezsensu w tym wypadku bo dajesz mozliwosc zainicjalizowania tamtych pol.

OK. Rozumiem już o jaki typ bezsensowności wam chodzi :D

0

Mam nadzieję, że zostanie mi wybaczone pisanie posta pod postem, zrobiłem jednak ponowny research i doszedłem do źródła moich wątpliwości. Wytłumaczę to zaraz, co mam nadzieję może przydać się kiedyś "dla potomnych" ;)

Możliwość umieszczenia na liście inicjalizacyjnej konstruktora tej samej klasy jest zasługą wprowadzonej w C++11 delegacji konstruktorów. Wcześniej taka operacja nie była możliwa (co sprawdziłem w g++). Z tego też wynikły moje wątpliwości - większość mojej literatury pochodzi jeszcze sprzed C++11 :P - dlatego też nie byłem pewien wpływu takiego podejścia na obiekty.
Pozwoliło to na ograniczenie ilości kodu w sytuacji gdy kilka konstruktorów potrzebuje wykonać te same zadania (jak testy poprawności czy specjalne inicjalizacje).
Możecie uznać, że próbuję się wykłócać uważam jednak, że nie ma nic "bezsensownego" w takim podejściu - konstruktor domyślny odpowiedzialny jest za część inicjalizacji wspólną dla większości pozostałych przypadków a dodatkowo jest prywatny, ze względu na chęć ograniczenia możliwości tworzenia na jego podstawie nie całkiem dokończonych obiektów z zewnątrz, i to wg. mnie "bez sensu" jest twierdzenie, że konstruktor domyślny ma być publiczny.

0

Czy ty po prostu sam nie komplikujesz sobie życia?

class Mapa {
private:
  float const evaporate_rate;
  float const alpha;
  float const beta;
  int size;
  /*...*/
public:
  static const float DefaultEvaporateRate;
  static const float DefaultAlpha;
  static const float DefaultBeta;

  explicit Mapa(float evaporate_rate = DefaultEvaporateRate, float alpha = DefaultAlpha, float beta = DefaultBeta);
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1