Wpis z mikrobloga

#pytanie #cpp #programowanie

1. Czy jak zrobie taką sytuację:

np:
B - klasa bazowa
D : B - klasa pochodna

B* p;

*p = D(paramtery konstruktora...);

to obiekt utworzy mi się na stercie i muszę w takim wypadku pamiętać o delete?
i czy utworzy mi się normalny pełnoprawny obiekt klasy D (jedynie dostęp będę miał ograniczony przez pryzmat wskaźnika jako do klasy B) ?

2. Jak mogę bezpośrednio stworzyć obiekt klasy pochodnej i przypisać go do wskaźnika klasy bazowej tak jak powyżej ale w przypadku gdy mam vektor wskaźników? np (oznaczenia B i D jak powyżej):

vector v;

v.push_back( D(paramtery konstruktora...) ?co jeszcze? );
  • 32
@PanCogito: do tworzenia obiektów na stercie używa się słowa new, czyli:

*p = new D(paramtery konstruktora...);
v.push_back( new D(paramtery konstruktora...) ?co jeszcze? );

musisz oczywiście później pamiętać o zwalnianiu pamięci za pomocą delete.
@PanCogito: mea culpa, coś mi się wydawało.

Ale to nie powinno zadzałać. Dlatego że przypisujesz do wskaźnika obiekt tymczasowy (który zostanie usunięty odrazu po utworzeniu).

Bez new obiekt jest zawsze tworzony na stosie.
@psychob: obiekt tymczasowy jest tworzony, a jego wartość jest przypisywana (kopiowana) pod adres na który wskazuje p. czyli na dobrą sprawę nie wiadomo gdzie bo p nie ma zainicjalizowanej wartości.
@PanCogito: Jak dla mnie to ten kod tworzy tymczasowo obiekt D, a następnie przepisuje jego pola (operator przypisania i te sprawy, i to chyba nie wszystkie, bo wystąpi tu slicing?) do jakiegoś losowego miejsca, na które wskazuje p, interpretując miejsce na które on wskazuje - prawdopodobnie błędnie - jako obiekt typu B. Nie wiem na co wskazywał p, ale coś nadpisałeś i przypadek sprawił, że program się nie wywalił...

Moja wiedza
@inplaz: @Almagest: @psychob: @blisher: Z tym " *p = D(paramtery konstruktora...); "
wiem że tak się nie powinno robić ale chciałem zapytać bo w jakiejś książce przeczytałem że obiekt się stworzy ale coś będzie z nim ogólnie nie tak (nie mogę teraz znaleźć gdzie to było).

Czyli nie mogę bezpośrednio stworzyć i przypisać do wskaźnika jakiegoś obiektu tak żeby nie był on na stercie.
Chodzi mi o to
@PanCogito: najbliżej tego co opisujesz jest wyżej wspomniany std::unique_ptr, ale w tym wypadku obiekt i tak jest alokowany na stercie, tylko jest ładnie opakowany. Możesz też zrobić obiekt lokalnie, i przypisać jego adres do wskaźnika ale nie będzie on dostępny TYLKO przez wskaźnik.
@inplaz: @psychob:
w sumie jak tak myślę nad tym to trochę kombinuje. Właściwie to po to się właśnie rzeczy umieszcza na stercie żeby takie coś można było robić muszę tylko potem pamiętać o delete.
Przesiadłem się z C# a tam się takie rzeczy robiło automatycznie ale garbage collector skrzętnie ukrywał całą mechanike.
@PanCogito: a tak w ogóle to starasz się pojąć naturę wskaźników czy szukasz rozwiązania dla jakiegoś konkretnego problemu? bo jeśli to drugie to takim kombinowaniem prosisz się o kłopoty.