c++ c++11 inheritance copy-constructor

c++ - El constructor de copia no se hereda



c++11 inheritance (3)

Tengo el siguiente código:

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 }

La clase derivada debe heredar todos los ctors de base excepto el ctor predeterminado (se explica here ). Pero, ¿por qué copiar ctor no se hereda también? Los argumentos de la pregunta relacionada no son aceptables aquí.

El código se compila con g ++ 4.8.1.


La clase derivada debe heredar todos los ctors de base excepto el ctor predeterminado

No, eso no es cierto, vea la respuesta de TC para la regla real.

El propósito de heredar constructores es decir "el tipo derivado se puede crear a partir de los mismos argumentos que el tipo base", pero eso no es relevante para el constructor de copia de la clase base, porque un constructor de copia no es solo una forma de decir cómo crear un tipo a partir de un argumento dado.

Un constructor de copia es especial, es para copiar un objeto del mismo tipo.

Un constructor D(const C&) no se usaría para copiar un objeto del mismo tipo, porque C no es del mismo tipo que D


Por un momento, asumiremos que está permitida la "herencia del constructor de copia". Con su estructura de clase intacta, considere el siguiente código para el método principal modificado.

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 }

En D d_from_d(d) , como una llamada de constructor normal, habrá dos llamadas de constructor de copia. Uno para C :: C (const C &) y el otro para el constructor de copia generado por el compilador para D. Teniendo el tipo de objeto fuente en D (d en este caso), el constructor de copia de C puede copiar los atributos de C de d mientras el constructor de copia de D generado por el compilador puede copiar el atributo D de d.

Pero en el caso D d_from_c(c) , no hay ningún problema para el constructor de copias de C porque los atributos C de c pueden ser copias del constructor de copias de C. Pero, ¿cómo sabe el compilador que genera el constructor de copias de D la forma de copiar los ''atributos de D del objeto de C''? Este es un conflicto que debe evitarse.

Pero, si proporciona algún tipo de ''constructor de copia extraño'' (puede que también necesite un constructor predeterminado) como;

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

Luego, llamando a D d_from_c(c); es válida. Porque, ahora hemos proporcionado explícitamente un constructor de ''copia'' coincidente.

Por lo tanto, decir ''Heredar constructores de copia ahora están permitidos'' no es válido.


Porque el estándar lo dice así. [class.inhctor] / p3, énfasis mío:

Para cada constructor que no sea de plantilla en el conjunto candidato de constructores heredados que no sea un constructor que no tenga parámetros o un constructor de copia / movimiento que tenga un solo parámetro , un constructor se declara implícitamente con las mismas características de constructor a menos que haya un constructor declarado por el usuario con la misma firma en la clase completa donde aparece la declaración de uso o el constructor sería un constructor predeterminado, de copia o de movimiento para esa clase.