2012-06-26 1 views
1

C++에서 이해할 수없는 부분이 있습니다. gcc는 어떻게 진행해야 하는지를 좋아하지 않습니다.
은 내가 그랬어 :C++ : if/else에서 선언 : var가이 범위에서 선언되지 않았습니다.

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

나는이 오류 얻을 : 자신의 타입이 fModeMdi 부울에 의존하기 때문에,

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을 선언 할 수 있습니다.
어떻게 해결할 수 있습니까?

+0

두 클래스의 상속 계층 구조가 있습니까? – hmjd

+0

"main"이 사용되는 일부 컨텍스트와 클래스 정의가 제공되어야합니다. 우리는 코드가 어떻게 구현되는지 추측 할 수 없습니다. – mfontanini

답변

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 문 내에서 정의 했으므로 변수가 이미 범위를 벗어 났고 더 이상 참조 할 수 없습니다.

+2

'MySecondClass'가 (직접 또는 간접적으로)'MyFirstClass'에서 파생되지 않으면 어떻게 될까요? – Nawaz

+0

'MySecondClass * '를'MyFirstClass *'에 캐스트하는 것이 좋다고 가정 할 수있는 한. – JoeFish

+0

네, 맞습니다. 나는 OP가 같은 이름의 2 개의 변수를 사용하고 있기 때문에, 그 타입들은 호환 가능하다고 생각했다. 그가 클래스 정의를 제공했다면 다른 접근법이 사용될 수 있습니다. – mfontanini

1

다음이 작동합니다. C++에서 변수의 범위는 대괄호 {} 안에 있으며 대괄호 안에 만 인식됩니다. 일단 나가면 프로그램은 그것에 대해 모른다.

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

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

적어도 하나의 초기화되지 않은 포인터가 있습니다. – hmjd

+0

미안 해요, 초기화되지 않았습니다 –

1

C++는이 라인 컴파일러는 컴파일시에 (정적, 따라서 이름)에서 main의 유형을 알고있다

int i = main->GetNum(); 

에서 정적으로 입력 된 언어입니다. main의 유형을 런타임에만 알려진 일부 값인 fModeMdi에 의존 할 수 없습니다. 각 클래스는 당신이 if 문 다음에 사용하는 방법 GetNum 등을 포함 할 경우,이 같은 기본 클래스로 이동 고려할 수 :

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 문을 사용할 필요가 없어집니다. 이것은 다형성 (polymorphism)이라고 불리는 것입니다.이 목적은 if 또는 switch 문을 사용할 필요가 없도록하는 것입니다.

+0

Crikey 이것은 내가 게시하려고했던 단어입니다. 너 빨리! – JoeFish

2

i와 루프의 값을 지정하십시오.

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

만약 MyFirstClassMySecondClass은 다음 @unkulunkulu는 그의 대답에 무엇을 제안 할 수있는, 상속을 통해 관련 있습니다.

MyFirstClassMySecondClass관련이없는 클래스가있는 경우 그러나, 당신은 템플릿을 사용할 수 있습니다이 그

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

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

참고 :

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

do_work과 같이 구현 된 함수 템플릿입니다 템플릿 솔루션은 관련성이 있어도 작동합니다!

0

main이 다형성이 아닐 수도있는 경우 올바른 해결책으로 보이는 것은 functor (또는 function object)입니다. boost functionboost bind은 이러한 라이브러리를 제공합니다. 아래의 프로그램에서 메모리 누수를 무시

, 우리는 각각의 GetNum() 통화를 대상 new A() 또는 new B()을 결합하고, 호출 가능한 객체에 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; 
} 
관련 문제