wake-up-neo.com

Umfang der Variablen in if-Anweisungen

Ich habe eine Klasse, die über keinen Standardkonstruktor oder Zuweisungsoperator verfügt. Daher wird sie innerhalb einer if/else -Anweisung abhängig vom Ergebnis einer anderen Funktion deklariert und initialisiert. Dann heißt es, dass es später außerhalb des Gültigkeitsbereichs liegt, obwohl beide Routen der Bedingung eine Instanz erstellen. 

Betrachten Sie das folgende Beispiel (getan mit int, um nur den Punkt zu veranschaulichen):

#include <iostream>

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

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

Werden in einer Bedingung deklarierte Variablen am Ende der Bedingung außerhalb des Gültigkeitsbereichs? Was ist der richtige Weg, um mit der Situation umzugehen, in der es keinen Standardkonstruktor gibt, die Argumente für den Konstruktor jedoch von bestimmten Bedingungen abhängen?

Bearbeiten

In Anbetracht der gegebenen Antworten ist die Situation komplexer, sodass sich der Ansatz möglicherweise ändern müsste. Es gibt eine abstrakte Basisklasse A und zwei Klassen B und C, die von A abgeleitet sind.

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

den Ansatz ändern? Da A abstrakt ist, konnte ich nicht einfach A* obj deklarieren und den entsprechenden Typ mit new erstellen. 

24
tpg2114

"Werden in einer Bedingung deklarierte Variablen am Ende der Bedingung außerhalb des Gültigkeitsbereichs?"

Ja - Der Gültigkeitsbereich einer lokalen Variablen liegt nur in einschließenden Klammern:

{
   int x; //scope begins

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

In Ihrem Fall sagen Sie, Sie haben class A.

Wenn Sie sich nicht mit Zeigern beschäftigen:

A a( condition ? 1 : 2 );

oder wenn Sie einen anderen Konstruktorprototyp verwenden:

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

Wenn Sie die Instanz auf dem Heap erstellen:

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

oder Sie könnten den ternären Operator verwenden:

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

BEARBEITEN:

Ja du könntest:

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

BEARBEITEN:

Es scheint, dass Sie nach dem Fabrikmuster suchen (nachschlagen):

 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;
    }
 };
21
Luchian Grigore

Werden in einer Bedingung deklarierte Variablen am Ende von .__ außerhalb des Gültigkeitsbereichs liegen? die Bedingung

Ja.

Was ist der richtige Weg, um mit der Situation umzugehen, wo es keine .__ gibt. Standardkonstruktor, aber die Argumente für den Konstruktor hängen von .__ ab. bestimmte bedingungen?

Schreiben Sie eine Funktion, die einen Wert zurückgibt, von dem Sie kopieren.

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

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

Bearbeiten:

Da A abstrakt ist, konnte ich nicht einfach A * obj deklarieren und die .__ erstellen. passender Typ mit neuem.

Was meinst du? Genau so funktioniert dynamisches Tippen. Außer ich würde keinen Rohzeiger verwenden, würde ich einen unique_ptr verwenden.

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

Ja, es liegt außerhalb des Gültigkeitsbereichs, wenn in einer Bedingung, einer Schleife usw. deklariert wird. Ändert sich der Typ der Variablen abhängig von der Bedingung?

0
boba-feh

Ihre Alternative sind Zeiger:

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

Denken Sie daran, es zu löschen, wenn Sie damit fertig sind, oder verwenden Sie einen intelligenten Zeiger.

0
Dani