2011-03-23 14 views
8

Digamos que tengo el siguiente código en lo que se espera para convertirse en el próximo C++ estándar:constructores La herencia en C++ 0x

int f(int x) 
{ 
    std::cout << x; 
    return x * x; 
} 

struct A 
{ 
    A(int x) : m_x(x) {} 
    int m_x; 
}; 

struct B : A 
{ 
    using A::A; 
    B() : m_y(f(m_x)) {} 
    int m_y; 
}; 

int main() 
{ 
    B(5); 
} 

Sería esto llamar al constructor por defecto de B e imprimir 5 y establecer m_y = 25? ¿O no se ejecutará el constructor predeterminado de B y dejará m_y sin inicializar?

Y si este último, ¿cuál es la razón detrás de no llamar al constructor predeterminado B? Está bastante claro que el A (int) B hereda solo la inicialización A, y deja a B en un estado indeterminado. ¿Por qué elegiría C++ un comportamiento indefinido simplemente llamando al constructor predeterminado de B()? En gran medida, infringe el objetivo de la función heredar constructores.

Editar:

Tal vez esto se debe permitir:

using A::A : m_y(...) { std::cout << "constructing..." << std::endl; ...; } 
+1

m_y será inicializado, mediante el uso de A :: A, obtendrá algo como esto: B :: B (int x): A :: m_x (x) {}. O algo :) – hidayat

+0

C++ realmente elige compilar el código con error, ya que no proporciona el constructor predeterminado para A. No es un comportamiento indefinido :) – user396672

Respuesta

4

using A::A; declara implícitamente B(int) en la clase derivada. Eso es.

El resto de su programa no debería funcionar como esperaba. Porque está invocando B(int) con B(5), y eso deja m_y sin inicializar.

Ver este ejemplo desde el sitio de Bjarne Stroustrup:

struct B1 { 
    B1(int) { } 
}; 

struct D1 : B1 { 
    using B1::B1; // implicitly declares D1(int) 
    int x; 
}; 

void test() 
{ 
    D1 d(6); // Oops: d.x is not initialized 
    D1 e;  // error: D1 has no default constructor 
} 

http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting

Otro ejemplo del mismo enlace:

struct D1 : B1 { 
     using B1::B1; // implicitly declares D1(int) 
     int x{0}; // note: x is initialized 
    }; 

    void test() 
    { 
     D1 d(6); // d.x is zero 
    } 
+0

Si D1 tenía un constructor predeterminado, ¿se ejecutaría al ejecutar la línea " D1 d (6); "? – Clinton

+0

Su ejemplo no declaró un constructor predeterminado para D1. Por supuesto, x no se inicializará, independientemente de "usar B1: B1". Mi ejemplo, sin embargo, declara un constructor predeterminado. – Clinton

+0

@Clinton: Sí. Pero el constructor predeterminado no se invoca en su ejemplo. Por lo tanto, no importa si lo define o no, invoca el constructor declarado implícitamente que es 'B (int)' en su ejemplo. – Nawaz