• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Różne warianty wywołania konstruktora .

VPS Starter Arubacloud
0 głosów
856 wizyt
pytanie zadane 18 stycznia 2017 w C i C++ przez dociekliwy Nowicjusz (150 p.)

Witam ponownie.

Kontynuuje czytanie książki Praty o C++ , przerabiam teraz klasy, konstruktory itp.

Nie jest to może jakieś super ważne ale natknąłem się na pewną subtelność której nie potrafię wytłumaczyć

 

#include <iostream>

using namespace std;
class xyz  //deklaracja klasy
{
    int zmienna_a;
    int zmienna_b;
public:
    xyz();  //konstruktor domyslny
    ~xyz(); //destruktor
    xyz(xyz &); //konstruktor kopiujacy

};

int main()
{
    xyz a1; //wywolanie konstruktora domyslnego
    xyz a2=a1;//wywolanie konstruktora kopiujacego niejawne.
    //Prata w ksiazce o C++ pisze ze konstruktor kopiujacy jest wywolywany
    //zawsze gdy tworzony jest nowy obiekt, a jego utworzeniu towarzyszy
    //inicjalizacja innym obiektem tej samej klasy. Wyprobowalem kilka zapisow
    // i tak.
    xyz a3(a1);//wywolanie konstruktora kopiujacego teraz jawne.
    //a tutaj mam wlasnie problem
    xyz a4=xyz(a1);//zakladalem ze tutaj rowniez bedzie wywolanie jawne konstruktora
    //kopiujacego ale wywala blad. Dopiero gdy w prototypie konstruktora kopiujacego
    //oznacze parametr jako const czyli xyz(const xyz&); to moge wywolac w ten 
    //sposob ten konstruktor, czemu w takim zapisie wymagany jest parametr const?
    //wiec zakladam ze skoro 
    xyz a5=a1;//taki zapis dziala, czyli niejawne wywolanie konstruktora to jest on
    //wywolywany tak naprawde tak xyz a5(a1); skoro taki zapis xyz a5=xyz(a1); Wymaga
    //parametru const . Dobrze rozumuje?
    return 0;
}
xyz::xyz()
{
    cout<<"domyslny\n";//komunikat diagnostyczny
    zmienna_a=0;
    zmienna_b=0;
}
xyz::~xyz()
{
    cout<<"destruktor\n";//komunikat diagnostyczny
}
xyz::xyz(xyz &r)
{
    cout<<"kopiujacy\n";//komunikat diagnostyczny
    zmienna_a=r.zmienna_a;
    zmienna_b=r.zmienna_b;
}

Będę wdzięczny za jakieś podpowiedzi .

 

 

1 odpowiedź

0 głosów
odpowiedź 18 stycznia 2017 przez adrian17 Ekspert (344,100 p.)
xyz a4=xyz(a1);

Bo to nie jest jedno wywołanie konstruktora. Pierwsza część:

xyz(a1)

Tworzy obiekt tymczasowy typu xyz wywołując konstruktor kopiujący. Ten obiekt jest tymczasowy, więc zniknie po zakończeniu tej linii.

xyz a4= (...)

Tworzy obiekt a4 próbując wywołać konstruktor kopiujący używając jako argument powyższy obiekt tymczasowy. Ale referencje do obiektów tymczasowych muszą mieć const, dlatego program się nie kompiluje.

Przy okazji, kanonicznie konstruktor kopiujący powinien brać const& jako argument.

Przy okazji [2], książka Praty nie zbiera dobrych recenzji.

komentarz 18 stycznia 2017 przez dociekliwy Nowicjusz (150 p.)

Dzięki za zainteresowanie tematem.

Dodałem do prototypu konstruktora zapis const aby skompilować program.

Nie do końca zgodzę się że przy takim zapisie

    xyz a1;
    xyz a2=xyz(a1);

zawsze jet tworzony obiekt tymczasowy przez konstruktor kopiujący.

Stosując ten zapis może być utworzony obiekt tymczasowy ale nie musi.

Jak to ładnie napisał Prata uzależnione jest to od implementacji .

A u mnie nie jest tworzony obiekt tymczasowy, ponieważ na zakończenie programu mam 

dwa wywołania destruktorów , dla obiektu a1 i a2.

I to mnie właśnie zgubiło , wiedząc że u mnie nie jest tworzony obiekt tymczasowy

myślałem że mogę przekazać parametr do takiego wywołania jako nie const.

Dopiero teraz zrozumiałem ( mam nadzieję że prawidłowo ) że jeżeli nawet nie jest 

tworzony obiekt tymczasowy to i tak musimy przekazać parametr jako const, jest

to zabezpieczenie na wypadek gdyby jednak był tworzony obiekt tymczasowy.

Ma to sens co napisałem?

komentarz 18 stycznia 2017 przez criss Mędrzec (172,590 p.)

Dopiero teraz zrozumiałem ( mam nadzieję że prawidłowo ) że jeżeli nawet nie jest 

tworzony obiekt tymczasowy to i tak musimy przekazać parametr jako const, jest

to zabezpieczenie na wypadek gdyby jednak był tworzony obiekt tymczasowy.

Ma to sens co napisałem?

Nie bardzo. Jak działa, to działa. Nie ma że "na wszelki wypadek nie działa".

To, że masz tylko dwa wywołania destruktora, to efekt jakichś optymalizacji kompilatora. Ciężko powiedzieć co się konkretnie stało. Przynajmniej ja nie potrafie. 

komentarz 18 stycznia 2017 przez adrian17 Ekspert (344,100 p.)
To, czy koniec końców jest tworzony obiekt tymczasowy, nie ma wpływu na poprawność kodu. Przy kompilacji brane jest pod uwagę że obiekt tymczasowy powstanie (nawet jeśli zostanie to potem zoptymalizowane), więc program się nie skompiluje.

Natomiast C++17 lekko zmienia te reguły i możliwe że Twój kod będzie się wtedy kompilował.
komentarz 18 stycznia 2017 przez criss Mędrzec (172,590 p.)
Mógłbyś przybliżyć co tutaj wprowadza c++17, bo chyba nie kojarze nic na ten temat?
1
komentarz 18 stycznia 2017 przez adrian17 Ekspert (344,100 p.)
komentarz 31 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
@dociekliwy zerknij tu: http://forum.pasja-informatyki.pl/204469/kopia-plytka-vs-kopia-gleboka-w-c Ps.: Skończyłem czytać tą książkę.
komentarz 31 stycznia 2017 przez criss Mędrzec (172,590 p.)
@Evelek - nie rozumiem jaki związek ma podesłany przez ciebie temat z moim pytaniem. A wszystko co tłumaczył adrian w zalinkowanym temacie jest mi dobrze znane.
komentarz 31 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

@dociekliwy zerknij tu:

Criss, czy to wygląda tak, jakbym się zwracał do ciebie? smiley Może dociekliwy tu jeszcze zajrzy i sobie doczyta z mojego linka.

komentarz 31 stycznia 2017 przez criss Mędrzec (172,590 p.)
No myślałem, że to ja jestem tym dociekliwym :D Bo w końcu byłem dociekliwy pytając co dokładnie adrian miał na myśli. Anyway - w takim razie nieważne. Miłego dnia :)
komentarz 31 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Haha zabawna sytuacja. :D Również miłego. ;)

Podobne pytania

0 głosów
3 odpowiedzi 185 wizyt
pytanie zadane 31 marca 2020 w C i C++ przez Adalm Początkujący (290 p.)
0 głosów
1 odpowiedź 339 wizyt
pytanie zadane 22 grudnia 2019 w C i C++ przez Jacuchna0 Użytkownik (640 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...