2012-03-02 12 views
5

probablemente sea súper fácil, pero ¿alguien puede decirme cómo puedo llamar al constructor de la superclase con los argumentos calculados en el constructor de la subclase? algo como esto:C++ constructor de clase de llamada con argumentos calculados

class A{ 
    A(int i, int j); 
}; 

class B : A{ 
    B(int i); 
}; 

B::B(int i){ 
    int complex_calculation_a= i*5; 
    int complex_calculation_b= i+complex_calculation_a; 
    A(complex_calculation_a, complex_calculation_b); 
} 

// editar: i editado el ejemplo para que la superclase toma dos argumentos que tienen una relación entre sí

Respuesta

4

Si no puede expresar su cálculo en una expresión de una sola línea, añadir una función estática, y lo llaman en la forma en que normalmente se llama al constructor de la superclase:

class B : A{ 
public: 
    B(int i) : A(calc(i)) {}; 
private: 
    static int calc(int i) { 
     int res = 1; 
     while (i) { 
      res *= i--; 
     } 
     return res; 
    } 
}; 

EDITAR caso múltiple-argumento:

class B : A{ 
public: 
    B(int i) : A(calc_a(i), calc_b(i)) {}; 
private: 
    static int calc_a(int i) { 
     int res = 1; 
     while (i) { 
      res *= i--; 
     } 
     return res; 
    } 
    static int calc_b(int i) { 
     int complex_a = calc_a(i); 
     return complex_a+10; 
    } 
}; 
+0

está bien - y si el constructor de la superclase toma varios argumentos? – Mat

+0

@Mat Debería definir una función separada para calcular el valor de cada parámetro que no puede o no quiere "en línea" como expresión. – dasblinkenlight

+0

pero los argumentos calculados pueden depender el uno del otro, ¿cómo puedo resolver eso con diferentes funciones? – Mat

1

Sólo de esta manera:

class A{ 
    A(int i); 
}; 

class B : A{ 
    B(int i); 
}; 

B::B(int i) : A(i*5) { 
} 

La llamada al constructor del padre solo puede venir en la lista de inicialización. Lo que significa, que debe ser conocido antes B está totalmente construido lo que estás cálculo (es decir: no se puede llamar a una función B miembro, a menos que su static, pero sólo depender de los parámetros pasados ​​a B)

+0

bien - en este caso, mi ejemplo era malo. Necesito hacer varias llamadas a funciones, bucles, bifurcación condicional, etc. para calcular los argumentos – Mat

+0

@Mat, como dije, solo puede hacer esto en una función externa (ya sea global o un miembro de clase estática, o una función miembro de un objeto pasado a 'B'). 'B' no existe cuando se llama' A'. – littleadv

3
B::B(int i) 
    : A(i * 5) 
{} 

Con C++ 11, una forma más compleja es

B::B(int i) 
    : A(([](int x) { return 5 * x; })(i)) 
{} 

Para los casos complejos, un init función protegida es más legible.

1
struct A 
{ 
    A(int); 
}; 

struct B : public A 
{ 
    B() 
     : A(5) // "initialisation list" 
    {} 
}; 

Tienes que hacer esto dentro de la lista, pero puedes usar una función. Editar: Si se utiliza una función, es probable que desee para que sea un miembro estático privada de B.

0
class A 
{ 
public: 
    A(int i){} 
}; 


class B : public A 
{ 
public: 
    B(int i):A(i*5){} 
}; 
Cuestiones relacionadas