【问题标题】:Scope of variables in if statementsif 语句中的变量范围
【发布时间】:2011-12-17 06:46:23
【问题描述】:

我有一个没有默认构造函数或赋值运算符的类,因此它根据另一个函数的结果在 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 创建适当的类型。

【问题讨论】:

  • 你的继承是虚拟的还是静态的?
  • 虚拟的,我想。 class A 有一个虚函数,如果这就是你的意思(C++ 不是我的强项,我主要在 Fortran 中工作)
  • 您实际上可以声明一个指向抽象类的指针 - 我编辑了我的答案。

标签: c++ constructor scope


【解决方案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 )
{
   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;
    }
 };

【讨论】:

  • 这种情况下内存是否被重新分配??在封闭的 { } 括号之后变量范围结束之后。
【解决方案2】:

条件语句中声明的变量是否在末尾超出范围 有条件的?

是的。

什么情况下正确处理没有 默认构造函数,但构造函数的参数取决于 某些条件?

编写一个返回值的函数,从中复制。

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

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

编辑:

由于 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));
}

【讨论】:

  • 这个答案与第一个答案相矛盾? (关于条件中声明的变量是否会在条件结束时超出范围)
  • @Gnuey:不,它没有。我不确定 Luchian 对哪个问题的回答是“不”。也许他只是在阅读问题的时间和写答案的时间之间混淆了措辞。但是完整的声明,以及它后面的注释代码 sn-p,显然同意我的回答。
【解决方案3】:

是的,如果在条件、循环等中声明,它将超出范围。变量的类型会根据条件而改变吗?

【讨论】:

  • 所以两种情况都有。有时它与条件无关,它是相同的类型,有时它是不同的类型,具体取决于条件。对于这两种情况,方法将如何变化?
  • 我有。我看到它如何解决第一种情况(相同类型)。它如何解决基于条件声明不同类型的可能性?
【解决方案4】:

您的替代方案将是指针:

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

记得在完成后删除它,或者使用智能指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 2013-08-14
    相关资源
    最近更新 更多