Подтвердить что ты не робот

Объем переменных в операторах if

У меня есть класс, который не имеет конструктора по умолчанию или оператора присваивания, поэтому он объявляется и инициализируется внутри оператора if/else в зависимости от результата другой функции. Но потом он говорит, что позже он выходит из сферы действия, хотя оба маршрута условного выражения создадут экземпляр.

Рассмотрим следующий пример (сделанный с помощью int только для иллюстрации точки):

#include <iostream>

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

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

Переменные, объявленные в условном выражении, выходят за пределы области действия в конце условного выражения? Каков правильный способ обработки ситуации, когда нет конструктора по умолчанию, но аргументы конструктора зависят от определенных условий?

Edit

В свете приведенных ответов ситуация более сложная, поэтому, возможно, этот подход должен измениться. Существует абстрактный базовый класс A и два класса B и C, которые выводятся из A. Как это было бы так:

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

изменить подход? Поскольку A является абстрактным, я не мог просто объявить A* obj и создать соответствующий тип с помощью new.

4b9b3361

Ответ 1

"Переменные, объявленные в условном выражении, выходят за пределы области действия в конце условного выражения?"

Да - область локальной переменной попадает только в круглые скобки:

{
   int x; //scope begins

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

В вашем случае, скажем, у вас есть class A.

Если вы не имеете дело с указателями:

A a( condition ? 1 : 2 );

или если вы используете прототип другого конструктора:

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

Если вы создаете экземпляр в куче:

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

или вы можете использовать тернарный оператор:

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

EDIT:

Да, вы могли бы:

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

EDIT:

Кажется, что вы ищете шаблон factory (посмотрите его):

 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;
    }
 };

Ответ 2

Переменные, объявленные в условном выражении, выходят за пределы области действия в конце условное?

Да.

Каков правильный способ справиться с ситуацией, когда нет конструктор по умолчанию, но аргументы для конструктора зависят от определенные условные обозначения?

Напишите функцию, которая возвращает значение, из которого вы копируете.

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

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

Edit:

Так как A абстрактно, я не мог просто объявить A * obj и создать соответствующий тип с новым.

Что ты имеешь в виду? Именно так работает динамический ввод. За исключением того, что я не использовал бы необработанный указатель, я бы использовал 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));
}

Ответ 3

Да, это будет вне области действия, если объявлено в условном, цикле и т.д. Будет ли тип переменной изменяться в зависимости от условного?

Ответ 4

Ваша альтернатива будет указателем:

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

Не забудьте удалить его, когда вы закончите с ним, или используйте интеллектуальный указатель.