2015-02-11 9 views
10

Mam następujący kod:Kopiowanie konstruktor nie jest dziedziczona

class C { 
public: 
    C(int) {} 
    C(const C&) {} 
    C() {} 
}; 

class D : public C { 
public: 
    using C::C; 
}; 

int main() { 
    C c; 
    D d_from_c(c); // does not compile, copy ctor is not inherited 
    D d_from_int(1); // compiles, C(int) is inherited 
} 

pochodna klasa powinna dziedziczyć wszystkie ctors z bazy wyjątkiem domyślnego ctor (to jest wyjaśnione here). Ale dlaczego kopiowanie ctor nie jest również dziedziczone? Argumenty z tego pytania nie są tutaj akceptowane.

Kod jest skompilowany za pomocą g ++ 4.8.1.

Odpowiedz

12

Ponieważ standard tak mówi. [Class.inhctor]/P3 kopalni nacisk:

Dla każdego konstruktora bez matrycy z zestawu kandydującego dziedzicznych konstruktorów innych niż konstruktor o parametry lub nie konstruktora kopiowania/o jeden parametr, konstruktor jest niejawnie zadeklarowany z tymi samymi charakterystykami konstruktora, chyba że istnieje konstruktor deklarowany przez użytkownika z tą samą sygnaturą w pełnej klasie , gdzie pojawia się deklaracja użycia lub konstruktor byłby wartością domyślną, kopiowaniem lub przenoszeniem konstruktor dla tej klasy.

10

pochodna klasa powinna dziedziczyć wszystkie ctors z bazy wyjątkiem domyślny konstruktor

Nie, to nie prawda, patrz T.C.'s answer dla realnej władzy.

Celem dziedziczenia konstruktorów jest stwierdzenie, że "typ pochodny może być tworzony z tych samych argumentów, co typ podstawowy", ale nie jest to istotne dla klasy bazowej "konstruktor kopiowania, ponieważ konstruktor kopiowania nie jest po prostu sposób mówienia, jak utworzyć typ z danej argumentacji.

Konstruktor kopii jest specjalny, służy do kopiowania obiektu tego samego typu.

Konstruktor nie byłby używany do kopiowania obiektów tego samego typu, ponieważ C nie jest tego samego typu co .

0

Przez chwilę przyjmiemy, że "dziedziczenie konstruktora kopii" jest dozwolone. Mając strukturę klas nienaruszoną, rozważ następujący kod dla zmodyfikowanej metody głównej.

int main() { 
    C c; 
    D d; 
    D d_from_d(d); 
    D d_from_c(c); // does not compile, copy ctor is not inherited 
    D d_from_int(1); // compiles, C(int) is inherited 
} 

W D d_from_d(d), jako normalnego wywołania konstruktora, będzie dwa połączenia konstruktor kopiujący. Jeden dla C :: C (const C &), a drugi dla konstruktora kopiowania generowanego przez kompilator dla D. Mając typ obiektu źródłowego w D (d w tym przypadku), konstruktor kopii C może skopiować atrybuty D's C podczas kompilacji wygenerowanej przez D's kopii konstruktor może skopiować atrybut d's D.

W przypadku nie ma problemu z konstruktorem kopiowania C, ponieważ atrybuty C c mogą być kopiowane przez konstruktora kopii C. Ale w jaki sposób kompilator wygenerował konstruktora kopii D, który zna sposób kopiowania "atrybutów D'z obiektu C". Jest to konflikt, którego należy unikać.

Ale jeśli podasz jakiś "dziwny konstruktor kopii" (być może będziesz potrzebował domyślnego konstruktora);

D(const C & c):C(c){} 

Następnie nazywając D d_from_c(c); jest prawidłowy. Ponieważ teraz wyraźnie udostępniliśmy pasujący konstruktor "kopiuj".

Tak więc powiedzenie "Dziedziczenie konstruktorów kopii jest teraz dozwolone" jest nieprawidłowe.

Powiązane problemy