2010-11-29 2 views
4

나는 사용자 입력에 따라 비슷한 일을하는 동일한 함수 이름을 가진 두 개의 클래스를 가지고있다. 나는 이런 식으로해야합니다.조건에서 객체를 선언하고 나머지 기능을 통해 사용할 수있게 만드는 방법은 무엇입니까?

if (myapp.advanced == true) 
    class1 a; 
else 
    class2 a; 

그러나 a는 if 내부에서 선언되었으므로 다음 줄에서 사용할 수 없습니다. 위의 조건을 어떻게 수정합니까?

+0

는'm의 값입니다 yapp.advanced'는 컴파일 타임에 알려진가요? –

+0

@Steve : 아니요, 프로그램을 실행할 때 사용자가 설정합니다. – thorvald

+0

'if (myapp.advanced) ' –

답변

2

공통 기본 클래스를 사용하여이 작업을 수행합니다 const 참조에 바인드

const base& a = (myapp.advanced == true) ? static_cast<base&>(class1()) 
             : class2(); 
a.something(); 
a.some_other_thing(); 
a.yet_another_thing(); 

임시직은 자신의 수명이 기준의 수명이 끝날 때까지 연장, 그래서이 안전합니다. 당신이 우려 객체 생성 및 다른 기능에를 사용 객체를 분리하는 경우에는 같은 해커는 (당신이 개체를 수정해야하는 경우 그리고 당신은 멀리 const과 함께 할 수있는) 필요하지 않을 것입니다 :

void do_something(base& obj) 
{ 
    obj.something(); 
    obj.some_other_thing(); 
    obj.yet_another_thing(); 
} 

if (myapp.advanced == true) { 
    class1 a; 
    do_something(a); 
} else { 
    class2 a; 
    do_something(a); 
} 

종류는 관련이없는 경우에도 함수 템플릿에 do_something()를 설정하여이 작업을 수행 할 수 있습니다 :

template< class T > 
void do_something(T& obj) 
{ 
    obj.something(); 
    obj.some_other_thing(); 
    obj.yet_another_thing(); 
} 

if (myapp.advanced == true) { 
    class1 a; 
    do_something(a); 
} else { 
    class2 a; 
    do_something(a); 
} 
+0

@sbi : 예, 다른 것을 추가했음을 알게 된 다음에는 걱정하지 않아도됩니다. Btw,'class1()'과'class2()'는 같은 타입을 가지고 있지 않기 때문에 3 진 표현식은 캐스트없이 컴파일되지 않습니다. 그 중 하나는'const base &'에 캐스트해야합니다. –

+1

@sgolodetz : 네 말이 맞아, 이것을 지적 해 주셔서 감사합니다! 나는 그것을 고쳤다. – sbi

+0

덧붙여 말하자면, 첫 번째 방법은 객체가'const' 일때 만 작동한다는 것입니다. 임시가 아닌 const 참조에 바인드 할 수 없기 때문입니다. 그러나 그들이 'const'가되는 것이 좋으면, 이것은 좋은 것에 대한 것입니다. –

1

기본 클래스에는 function something()을 순수 가상으로두고 class1과 class2를 상속하는 것이 좋습니다.

class Base 
{ 
public: 
    virtual void something() = 0; 
    virtual ~Base(){}; // since we use Base class pointer the destructor should be virtual 
}; 

class class1 : public Base 
{ 
public: 
    void something(){ //do stuff 
    } 
}; 
class class2 : public Base 
{ 
public: 
    void something(){ //do other stuff 
    } 
}; 

다음은이 기술의 사용 예제입니다 :

int main() 
{  
    Base* a = NULL; 

    if (myapp.advanced == true) 
     a = new class1(); 
    else 
     a = new class2(); 

    a->something(); 

    // when the instance is not needed anymore destroy it. 
    delete a; 
} 

프레드 Nurk이 코멘트에 언급 한 것처럼 delete 연산자를 사용하는 다른 대안있다 - auto_ptr은 다른 부스트 스마트 포인터를. 그들은 많은 사람들 (나 자신 포함)이 널리 사용하여 new으로 만든 오브젝트의 수명을보다 쉽게 ​​제어 할 수 있습니다. 영업 이익의 코멘트 다음

또 다른 편집

:
한 CPP로 헤더 (직접 또는 간접) 다수의 포함을 피하기 위해 헤더

#ifndef _SOME_UNIQUE_NAME_HERE_ 
#define _SOME_UNIQUE_NAME_HERE_ 

// header body goes here 

#endif 

에서 여러 포함 보호 매크로를 넣어하는 것을 잊지 마십시오. 내가 생각할 수있는

+0

a를 삭제하는 것을 잊지 마십시오. :-) 기본 클래스를 원하지 않으면 두 포인터를 사용하여 동일하게 할 수 있습니다. 그런 다음 NULL이 아닌 값을 통해 무언가를 호출하십시오. –

+0

+1, 이것은 인터페이스 + 2 구체 구현의 주요 후보로 보인다. –

+1

'Base :: something()','class1 :: something()','class2 :: something()'을 public으로 만들고, Base에 가상 소멸자를 추가 할 수 있습니다. –

3

두 가지 방법 :

1) 클래스 1을 확인하고 Class2의 몇 가지 기본 클래스 classB에서 파생은, 다음을 수행하십시오

template <typename T> void do_something(T& t) 
{ 
    t.something(); 
} 

... 

if(myapp.advanced) 
{ 
    class1 a; 
    do_something(a); 
} 
else 
{ 
    class2 a; 
    do_something(a); 
} 
:

shared_ptr<classB> a; 
if(myapp.advanced == true) a.reset(new class1); 
else a.reset(new class2); 
a->something(); 

2) 템플릿 함수를 작성

기본 클래스를 추가하기 위해 class1class2을 변경할 수없는 경우 두 번째 방법이 더 적합합니다. 또한 do_something 내부의 비트가 해당 객체의 something()을 호출하는 것보다 더 복잡하다고 가정합니다. 그렇지 않으면 그냥 직접 호출 할 수 있습니다!

편집 : 두 번째 방법은 문제의 나머지 기능에서 사용할 수 있도록하지 않습니다. 대신 사용할 수있는 새로운 기능이 추가됩니다.

2

코딩 논리에 따라 Class1과 Class2는 공통점이 있습니다. 공통 기본 클래스에서 코드를 파생시켜 코드에 표현하십시오. 그런 다음 기본 클래스 포인터를 사용하여 파생 클래스의 인스턴스를 보유합니다.

1

이 접근하는 방법에는 여러 가지가 있지만 추가 정보없이 아마 당신이 할 조언 것이다 : 나는 수업 자료라는 공통 조상이 있다고 가정

을 물론

Base* a; 
if (myapp.advanced == true) 
    a = new class1(); 
else 
    a = new class2(); 

당신은하지 않아야 더 이상 필요하지 않거나 스마트 포인터를 사용하면 delete을 발급해야합니다.

if-else 문을 반복해서 사용하는 경우이 절차는 일종의 함수 또는 팩토리 클래스로 래핑하는 것이 더 좋을 수 있지만 상황에 따라 다릅니다. 이러한 유형이 관련된 경우

+0

else 브랜치의 경우'a = new class2;'를 의미합니다 :) –

+1

예, 물론 고마워요. – Palmik

관련 문제