我有一个没有默认构造函数或赋值运算符的类,所以它在if / else语句中声明和初始化,具体取决于另一个函数的结果。但后来它表示它超出了范围,即使条件的两个路由都会创建一个实例。
考虑以下示例(仅使用int
完成以说明这一点):
#include <iostream>
int main()
{
if(1) {
int i = 5;
} else {
int i = 0;
}
std::cout << i << std::endl;
return 0;
}
在条件结尾处,条件中声明的变量是否超出范围?处理没有默认构造函数但构造函数的参数依赖于某些条件的情况的正确方法是什么?
修改
根据给出的答案,情况更复杂,因此可能必须改变方法。有一个抽象的基类A和两个从A派生的B和C类。如何这样:
if(condition) {
B obj(args);
} else {
C obj(args);
}
改变方法?由于A是抽象的,我不能只声明A* obj
并使用new
创建适当的类型。
答案 0 :(得分:22)
“在条件结束时,条件中声明的变量是否超出范围?”
是 - 局部变量的范围仅在括号内:
{
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 )
{
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 );
编辑:
是的,你可以:
A* x = NULL; //pointer to abstract class - it works
if ( condition )
x = new B();
else
x = new C();
编辑:
您正在寻找的是工厂模式(查找):
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;
}
};
答案 1 :(得分:4)
在条件中声明的变量在范围结束时超出范围 有条件的?
是
处理没有的情况的正确方法是什么 默认构造函数,但构造函数的参数依赖于 某些条件?
编写一个返回值的函数,从中复制。
T foo()
{
if(condition)
return T(x);
return T(y);
}
void bar()
{
T i(foo());
}
修改强>
你是什么意思?这正是动态类型的工作方式。除非我不使用原始指针,否则我将使用unique_ptr。由于A是抽象的,我不能只声明A * obj并创建 适当的类型与新。
std::unique_ptr<A> obj;
if(condition) {
obj = std::unique_ptr<A>(new B(args));
} else {
obj = std::unique_ptr<A>(new C(args));
}
答案 2 :(得分:0)
是的,如果在条件,循环等中声明,它将超出范围。变量的类型是否会根据条件而变化?
答案 3 :(得分:0)
你的选择将是指针:
MyObject *obj;
if(cond1)
{
obj = new MyObject(1, 2, 3);
}
else
{
obj = new MyObject(4, 5);
}
记得在完成后删除它,或者使用智能指针。