Konstruktor domyślny na liście inicjalizacyjnej

Konstruktor domyślny na liście inicjalizacyjnej
BH
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:4
0

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

Kopiuj
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:

Kopiuj
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):

Kopiuj
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 ;))?

edytowany 2x, ostatnio: eBinaryHelix
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
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...

MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:2 minuty
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.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
fasadin
niekoniecznie jest bezsensu. Jezeli chce wprowadzic inicjalizacje obiektu tylko poprzez... w sumie to bez sensu, bo i tak daje dostep do danych w innych konstruktorach
BH
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:4
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).

edytowany 4x, ostatnio: eBinaryHelix
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
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 ;)

edytowany 1x, ostatnio: fasadin
BH
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:4
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

MarekR22
Najwyraźniej wcale go nie potrzebujesz.
BH
To jak lepiej obsłużyć sytuację gdy w kilku miejscach tworzę obiekty mojej klasy na różne sposoby, w większości przypadków stałe w nich zawarte mają pewne standardowe na dzień dzisiejszy wartości (które w przyszłości mogą się zmienić, a wtedy wystarczy zmienić liczby w konstruktorze domyślnym)? Jest jednak jeden przypadek gdy potrzebuję inicjalizacji z pełnym zestawem parametrów co zapewnia ostatni z zaproponowanych konstruktorów.
MarekR22
konstruktor domyślny ma być albo publiczny, albo wcale nie jest potrzebny.
BH
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:4
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.

MO
No to doczytaj sobie jeszcze o default i delete dla konstruktorów w C++11.
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:2 minuty
0

Czy ty po prostu sam nie komplikujesz sobie życia?

Kopiuj
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);
}

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)