C ++:声明if / else:var未在此范围内声明

时间:2012-06-26 12:31:10

标签: c++ gcc variable-declaration

我不懂C ++中的内容,gcc不喜欢我该如何处理 我做了:

    if (!fModeMdi)
            MyFirstClass* main = (MyFirstClass*) fMaino;
    else
            MySecondClass* main = (MySecondClass*) fMdio;
    ...
    ...
    int i = main->GetNum();

我收到此错误:

file.C:211:16: warning: unused variable 'main' [-Wunused-variable]
file.C:213:15: warning: unused variable 'main' [-Wunused-variable]
file.C:219:9: error: 'main' was not declared in this scope

我无法在标题中声明main,因为他的类型取决于fModeMdi布尔值。
我该怎么解决这个问题呢?

6 个答案:

答案 0 :(得分:3)

如何在if语句之前定义变量,并在其中分配变量?

MyFirstClass* main = 0; // use nullptr if you have access to a C++11 compiler

if (!fModeMdi)
    main = (MyFirstClass*) fMaino;
else
    main = (MySecondClass*) fMdio;

由于您在if语句中定义了它,因此该变量已经超出范围且无法再引用。

答案 1 :(得分:3)

如果MyFirstClassMySecondClass 相关通过继承,那么你可以做@unkulunkulu在他的回答中提出的建议。

但是,如果MyFirstClassMySecondClass无关的类,那么您可以将模板用作:

if (!fModeMdi)
{
    do_work(static_cast<MyFirstClass*>(fMaino));
}
else
{
    do_work(static_cast<MySecondClass*>(fMaino));
}

其中do_work是一个函数模板,实现为:

template<typename T>
void do_work(T *obj)
{
    int i = obj->GetNum();

    //do rest of the work here....
}

请注意,即使模板解决方案相关,此模板解决方案仍可正常工作!!

答案 2 :(得分:2)

在循环中分配i的值。

int i;
if (!fModeMdi){
        MyFirstClass* main = (MyFirstClass*) fMaino;
        i = main->GetNum();
}else{
        MySecondClass* main = (MySecondClass*) fMdio;
        i = main->GetNum();
}

答案 3 :(得分:1)

以下内容应该有效。在c ++中,变量的范围在括号{}内,即它只能在括号内识别。一旦你出去,程序就不知道了。

MyFirstClass* main =0; 
MySecondClass* main2 =0; 

if (!fModeMdi)
            main = (MyFirstClass*) fMaino;
    else
            main2 = (MySecondClass*) fMdio;

答案 4 :(得分:1)

C ++是一种静态类型的语言,在这一行

    int i = main->GetNum();

编译器必须在编译时知道main的类型(静态,因此名称)。您不能使main的类型依赖于某些值fModeMdi,这仅在运行时才知道。如果您的每个类都包含一个方法GetNum以及您在if语句之后使用的其他类,则可以考虑将它们移动到这样的基类:

class MyBaseClass {
public:
    virtual int GetNum() = 0;
}

class MyFirstClass : public MyBaseClass {
    // ...
};


class MySecondClass : public MyBaseClass {
    // ...
};

MyBaseClass* main = 0;
if (!fModeMdi)
            main = (MyFirstClass*) fMaino;
    else
            main = (MySecondClass*) fMdio;
    ...
    ...

然后这是合法的

    int i = main->GetNum();

实际上,正确的设计(将常用方法移动到基类)可能完全不需要这个if语句。这就是所谓的多态性,它的全部目的是消除对这些ifswitch语句的需要。

答案 5 :(得分:0)

如果main可能不是多态的,那么看似正确的解决方案就是仿函数(或function object)。 boost functionboost bind提供了这些库。

忽略以下程序中的内存泄漏,我们将对象new A()new B()绑定到各自的GetNum()调用,并将它们包装在可调用对象f中。我们会在需要时致电f()

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

class A {
     public:
    int GetNum() { return 0; }
};

class B {
    public:
    int GetNum() { return 0; }
};

int main(int args, char** argv)
{

    bool p = true;
    boost::function<int()> f;
    int i;

    if ( p ) {
        f = boost::bind(&A::GetNum, new A());
    }
    else {
        f = boost::bind(&B::GetNum, new B());
    }

    i = f();

    std::cout<<i<<std::endl;

    return 0;
}