una tipos tener que puede programación programacion poo orientada objetos libro ejemplo cuantos constructores con codigo clase c++ inheritance constructor c++11

c++ - tipos - que es un constructor java



¿Usando constructores de clase base C++? (5)

Al trabajar con plantillas, me encontré con la necesidad de hacer que los constructores de una clase base accesibles desde las clases heredadas crearan objetos para disminuir las operaciones de copiar / pegar. Estaba pensando en hacer esto mediante el using palabra clave de la misma manera con el caso de las funciones, pero eso no funciona.

class A { public: A(int val) {} }; class B : public A { }; class C : public A { public: C(const string &val) {} }; class D : public A { public: D(const string &val) {} using A::A; // g++ error: A::A names constructor }; void main() { B b(10); // Ok. (A::A constructor is not overlapped) C c(10); // error: no matching function to call to ''C::C(int)'' }

Entonces mi pregunta: ¿hay alguna forma de importar un constructor de la clase base después de que se hayan declarado nuevos en la clase heredada?

¿O solo hay una alternativa para declarar nuevos constructores y llamar a los básicos de la lista de inicializadores?


Aquí hay una buena discusión sobre las reglas de llamada del constructor de superclase . Siempre quiere que se llame al constructor de la clase base antes del constructor de clase derivado para formar un objeto correctamente. Por eso se usa este formulario

B( int v) : A( v ) { }


No, así no es como se hace. La forma normal de inicializar la clase base está en la lista de inicialización:

class A { public: A(int val) {} }; class B : public A { public: B( int v) : A( v ) { } }; void main() { B b(10); }


Prefiero la inicialización:

class C : public A { public: C(const string &val) : A(anInt) {} };

En C ++ 11, puede usar constructores heredadores (que tienen la sintaxis que se ve en su ejemplo D ).

Actualización: Inheriting Constructors ha estado disponible en GCC desde la versión 4.8.

Si no encuentra atractiva la inicialización (por ejemplo, debido a la cantidad de posibilidades en su caso real), entonces puede favorecer este enfoque para algunas construcciones TMP:

class A { public: A() {} virtual ~A() {} void init(int) { std::cout << "A/n"; } }; class B : public A { public: B() : A() {} void init(int) { std::cout << "B/n"; } }; class C : public A { public: C() : A() {} void init(int) { std::cout << "C/n"; } }; class D : public A { public: D() : A() {} using A::init; void init(const std::string& s) { std::cout << "D -> " << s << "/n"; } }; int main() { B b; b.init(10); C c; c.init(10); D d; d.init(10); d.init("a"); return 0; }


Sí, desde C ++ 11:

struct B2 { B2(int = 13, int = 42); }; struct D2 : B2 { using B2::B2; // The set of inherited constructors is // 1. B2(const B2&) // 2. B2(B2&&) // 3. B2(int = 13, int = 42) // 4. B2(int = 13) // 5. B2() // D2 has the following constructors: // 1. D2() // 2. D2(const D2&) // 3. D2(D2&&) // 4. D2(int, int) <- inherited // 5. D2(int) <- inherited };

Para obtener información adicional, consulte http://en.cppreference.com/w/cpp/language/using_declaration


Tendrá que declarar constructores en cada una de las clases derivadas, y luego llamar al constructor de la clase base desde la lista de inicializadores:

class D : public A { public: D(const string &val) : A(0) {} D( int val ) : A( val ) {} }; D variable1( "Hello" ); D variable2( 10 );

C ++ 11 le permite utilizar el uso de la sintaxis A :: A en su declaración de D, pero las características de C ++ 11 no son compatibles con todos los compiladores en este momento, por lo que es mejor seguir con los métodos anteriores de C ++ hasta que este la característica se implementa en todos los compiladores con los que se usará su código.