2009-03-20 12 views
20

Rozumiem kopia konstruktora nazywa się na trzech przypadkachKonstruktor kopiowania w C++ jest wywoływany, gdy obiekt jest zwracany z funkcji?

  1. Przy uruchamianiu tego jednego obiektu i inicjowanie go z wartości z innego obiektu.
  2. Podczas przekazywania obiektu według wartości.

3. Gdy obiekt jest zwracany z funkcji według wartości.

Mam pytanie z nr 3 , jeśli konstruktor kopiowania jest wywoływany, gdy zwracana jest wartość obiektu, nie powinien powodować problemów, jeśli obiekt jest zadeklarowany lokalnie w funkcji.

mam na myśli konstruktora kopia jest głęboka kopia jeden i zajmuje odniesienia obiektu jako parametr

+3

Nie ma gwarancji, że konstruktor kopiowania zostanie wywołany w tych przypadkach, ponieważ standard C++ umożliwia kompilatorowi optymalizację kopii w niektórych przypadkach - w szczególności [optymalizację wartości zwracanej] (http: // pl .wikipedia.org/wiki/Return_value_optimization) – rmp251

+0

Odniesienie wskazane przez @ rmp251 wyraźnie odpowiada na to pytanie. –

Odpowiedz

15

To się nazywa dokładnie, aby uniknąć problemów. Nowy obiekt służący jako wynik jest inicjowany z obiektu zdefiniowanego lokalnie, a następnie lokalnie zdefiniowany obiekt jest niszczony.

W przypadku konstruktora zdefiniowanego przez użytkownika głęboko jest on taki sam. Pierwsza pamięć jest przydzielona dla obiektu, który będzie służył jako wynik, następnie wywoływany jest konstruktor kopiowania. Używa przekazanego odniesienia do uzyskania dostępu do obiektu zdefiniowanego lokalnie i kopiowania tego, co jest niezbędne do nowego obiektu.

0

Nie, nazywa go przed miejscowi są zniszczone. Możesz to sprawdzić za pomocą obiektu, który rejestruje zniszczenie i kopiowanie konstrukcji, lub patrząc na wygenerowany kod zespołu.

+0

, ale co się stanie, jeśli konstruktor kopiowania odniesie się jako parametr (głęboka kopia), w takim przypadku nie skopiuje całego obiektu, prawda? – Kazoom

+0

Zależy od konstruktora kopii. Domyślny konstruktor kopiuje według członków. Zwykle powinieneś zaimplementować swój konstruktor kopii tak, aby nie polegał na czasie życia obiektu, który został przekazany. Nie musisz wykonywać głębokiej kopii, ale musisz się upewnić, że udostępnione rzeczy pozostaną w pobliżu. –

11

Kopię wykonuje się przed wywołaniem wywoływanej funkcji i kopiuje istniejącą zmienną lokalną do wartości zwracanej.

Wywołana funkcja ma dostęp do pamięci, której wartość zwracana będzie zajmowana, mimo że ta pamięć nie jest "w zasięgu" podczas kopiowania, jest nadal dostępna.

+0

Rozumiem, że gdy zwracana jest wartość obiektu, najpierw wywołuje konstruktor kopiowania, ale konstruktor kopii jest zdefiniowany przez użytkownika, który odwołuje się jako parametr ClassA (const ClassA &), w takim przypadku, co by się stało? co się stanie, jeśli po prostu zwrócisz referencję zamiast wartości id logiki – Kazoom

+0

Jeśli funkcja jest zadeklarowana jako zwracająca wartość referencyjną, zwracająca referencję do zmiennej lokalnej jest duża, nie można jej zrobić. Zwrócisz referencję do obiektu, który zostanie odrzucony po powrocie funkcji. Korzystanie z tego odniesienia prawdopodobnie spowoduje problem, miażdżąc w komplecie. – sharptooth

+0

tak, rozumiem to, więc kiedy konstruktor kopiowania, który przyjmuje odwołanie jako parametr, jest wywoływany podczas zwracania wartości, co by się stało? czy to też nie powinno się zawiesić? – Kazoom

4

Według an answer na moje pytanie, konstruktor kopia można nazwać nawet dwukrotnie: raz, aby skopiować obiekt lokalnych na powrotny „obiektu”, a raz skopiować obiekt powrotu na zmiennej został przypisany.

Jednak to nie musi być być! Kompilator może zoptymalizować obie konstrukcje kopiowania.

+2

Nie zgadzam się z tobą. Kopiuj construtor został wywołany tylko raz na zwracającym obiekcie, podczas przypisywania zwróconego obiektu do innego zewnętrznego obiektu zasięgu, wywoływany jest operator przypisania, a nie konstruktor kopiowania. –

-1

Istnieją trzy ogólne przypadki, w których konstruktor kopia nazywa się:

  1. Przy uruchamianiu tego jednego obiektu i inicjowanie go z wartości z innego przedmiotu (tego samego typu).
  2. Podczas przekazywania obiektu według wartości.
  3. Gdy obiekt jest zwracany z funkcji według wartości.