Объем переменных в операторах 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
.
Ответы
Ответ 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);
}
Не забудьте удалить его, когда вы закончите с ним, или используйте интеллектуальный указатель.