2011-12-17 18 views
19

Tengo una clase que no tiene un constructor o un operador de asignación predeterminado, por lo que se declara y se inicializa dentro de una sentencia if/else dependiendo del resultado de otra función. Pero luego dice que está fuera del alcance más adelante aunque ambas rutas del condicional crearán una instancia.Alcance de variables en sentencias if

Considérese el siguiente ejemplo (hecho con int sólo para ilustrar el punto):

#include <iostream> 

int main() 
{ 
    if(1) { 
    int i = 5; 
    } else { 
    int i = 0; 
    } 

    std::cout << i << std::endl; 
    return 0; 
} 

No variables declaradas en un ir condicional fuera de alcance al final del condicional? ¿Cuál es la forma correcta de manejar la situación donde no hay un constructor predeterminado, pero los argumentos para el constructor dependen de ciertos condicionales?

Editar

A la luz de las respuestas dadas, la situación es más compleja así que quizás el enfoque tendría que cambiar. No es una clase base abstracta A y dos B y C clases que derivan de A. ¿Cómo sería algo como esto:

if(condition) { 
    B obj(args); 
} else { 
    C obj(args); 
} 

cambio del enfoque? Como A es abstracto, no pude simplemente declarar A* obj y crear el tipo apropiado con new.

+0

¿Su herencia es virtual o estática? – Dani

+0

Virtual, creo. 'clase A' tiene una función virtual, si eso es lo que quieres decir (C++ no es mi fuerte, yo trabajo principalmente en Fortran) – tpg2114

+0

En realidad puedes declarar un puntero a una clase abstracta; he editado mi respuesta. –

Respuesta

16

"¿Las variables declaradas en un condicional salen del ámbito al final del condicional?"

- el alcance de una variable local solamente se inscribe en corchetes que encierran:

{ 
    int x; //scope begins 

    //... 
}//scope ends 
//x is not available here 

En su caso, supongamos que tiene class A.

Si no está tratando con punteros:

A a(condition ? 1 : 2); 

o si estás usando un prototipo diferente constructor:

A a = condition ? A(1) : A(2,3); 

Si va a crear la instancia en el montón:

A* instance = NULL; 
if (condition = true) 
{ 
    instance = new A(1); 
} 
else 
{ 
    instance = new A(2); 
} 

o se puede utilizar el operador ternario:

//if condition is true, call A(1), otherwise A(2) 
A* instance = new A(condition ? 1 : 2); 

EDIT:

Sí se puede:

A* x = NULL; //pointer to abstract class - it works 
if (condition) 
    x = new B(); 
else 
    x = new C(); 

EDIT:

Parece lo que estás buscando es el patrón de la fábrica (mirar hacia arriba):

class A; //abstract 
class B : public A; 
class C : public A; 

class AFactory 
{ 
public: 
    A* create(int x) 
    { 
     if (x == 0) 
      return new B; 
     if (x == 1) 
      return new C; 
     return NULL; 
    } 
}; 
+0

¿Se ha reasignado la memoria en este caso? Después de que el alcance variable finalice después de los {} paréntesis adjuntos. – kaushalpranav

4

Variables declarado en un condicional fuera de alcance al final de el condicional?

Sí.

¿Cuál es la forma correcta de manejar la situación en la que no hay constructor por defecto, pero los argumentos para el constructor dependen de ciertas condicionales?

Escriba una función que devuelve un valor, desde el que copia.

T foo() 
{ 
    if(condition) 
     return T(x); 
    return T(y); 
} 

void bar() 
{ 
    T i(foo()); 
} 

Editar:

Dado que A es abstracta, no podía simplemente declarar un * obj y crear el tipo apropiado con uno nuevo.

¿Qué quieres decir? Así es exactamente como funciona la tipificación dinámica. Excepto que no usaría un puntero sin formato, usaría un unique_ptr.

std::unique_ptr<A> obj; 
if(condition) { 
    obj = std::unique_ptr<A>(new B(args)); 
} else { 
    obj = std::unique_ptr<A>(new C(args)); 
} 
+0

¿Esta respuesta contradice la primera respuesta? (acerca de si las variables declaradas en un condicional saldrán del alcance al final del condicional) – LazerSharks

+1

@Gnuey: No, no es así. No estoy seguro de a qué pregunta responde Luchian "No" a. Quizás solo confundió la verborrea entre el momento en que leyó la pregunta y el momento en que escribió la respuesta. Pero la declaración completa, así como el fragmento de código comentado que sigue, claramente concuerdan con mi respuesta. –

0

Sí, va a estar fuera de alcance si se declara en una condicional, bucle etc. ¿El tipo de cambio de la variable dependiendo de la condicional?

+0

Entonces hay dos casos. Algunas veces es del mismo tipo independientemente del condicional, a veces es un tipo diferente dependiendo del condicional. ¿Cómo cambiarían los enfoques para las dos situaciones? – tpg2114

+0

@ tpg2114 has leído mi respuesta? –

+0

Tengo. Veo cómo aborda el primer caso (el mismo tipo). ¿Cómo aborda la posibilidad de que se declaren tipos diferentes en función del condicional? – tpg2114

0

Su alternativa será punteros:

MyObject *obj; 
if(cond1) 
{ 
    obj = new MyObject(1, 2, 3); 
} 
else 
{ 
    obj = new MyObject(4, 5); 
} 

Recuerde eliminar cuando haya terminado con él, o utilizar un puntero inteligente.

+0

** Puedes ** utilizar punteros, pero no es necesario. –

Cuestiones relacionadas