2012-01-01 17 views
7

Tengo un miembro de clase A en mi propia clase cuyo constructor toma múltiples parámetros. Estoy reenviando los parámetros de mi propia clase al constructor de la clase A. Pero es importante que estos parámetros sean correctos, así que necesito verificarlos antes de crear el miembro de A. Y aquí está el problema: Podría omitir el miembro en el lista de intialización de miembros, llamando efectivamente al constructor predeterminado. Después de los controles en el constructor, podría llamar al constructor de A en una asignación. Aunque, esto produce un error ya que el destructor de A es privado.Ejecutar comprobaciones antes de la lista de inicialización

¿Cómo resuelvo esto?

MyClass::MyClass(int someParam) : otherMember(2){ 
//checks for someParam 
member = A(someParam); // <- produces error 
} 
+0

Hable con el autor de la clase 'A' y oblíguela a hacer que el propio constructor de' A' se comporte de forma sensata en caso de valores de parámetros ilegales. –

+0

¿Sería aceptable construir 'A' y luego verificar el hecho? – Cameron

+0

En realidad, intenté persuadir a Sun para que lo aceptara en Java, pero se negaron. Es un poco más fácil hacer trampas en Java porque puedes llamar a un constructor desde otro. – Neil

Respuesta

9

Necesitará un destructor accesible sin importar lo que haga. Sin embargo, para hacer frente a su pregunta, una opción sería llamar a una función estática para comprobar los parámetros desde dentro del inicializador:

class MyClass { 
    private: 
    static void checkParam(int); 
// ... 
}; 

MyClass::MyClass(int someParam) : otherMember((checkParam(someParam), 2)) { 
    // ... 
} 

static void MyClass::checkParam(int someParam) { 
    if (...) throw someException(); 
} 

Tenga en cuenta que la , utilizado no es el operador coma, no un separador de argumento - que evalúa tanto a la izquierda y expresiones correctas, y arroja el resultado de la izquierda.

+0

¿Las excepciones lanzadas en checkParam() aún interrumpirían el flujo de programas? Si la respuesta a esta pregunta es sí, esto es exactamente lo que necesito. Para aquellos de ustedes que se preguntan sobre el destructor privado, es una referencia contada objetada; Si uso el puntero de recuento de referencia adecuado sería mejor. – Paranaix

+0

Sí. checkParam se evaluará antes de '2', por lo que si se lanza,' 2' no se evaluará, y por lo tanto el constructor 'otherMember' no se puede invocar – bdonlan

0

veo dos formas de abordar este:

  1. Asegúrese de que la clase A se puede utilizar con un constructor sin parámetros, y establece someParam en un método separado: A.SetSomeParam(someParam)

  2. no hereda de A, pero mantenga un objeto miembro de tipo A, y luego puede construirlo cuando lo desee.

Cuestiones relacionadas