2010-11-21 6 views
0

나는 C++을 배우고 있으며 문제가 있습니다. 기본 클래스 내에서 특정 하위 클래스를 사용하는 방법이 필요합니다. 그것은 의미가 있습니까 또는 잘못된 접근 방식을 사용하고 있습니까? SelectBrand가 하위 클래스를 선택해야합니다. 어떻게해야합니까? 여기 내 간단 클래스 아래기본 클래스에서 하위 클래스를 선택할 수 있습니까?

:


----- 
class Protocol { 

public: 

    Protocol() {}; 
    ~Protocol() {}; 
    int openPort(); 
    int readPort(char *buffer); 

..... 

private: 

     Protocol (const Protocol&); 
}; 

int Protocol::openPort() {......}; 

int Protocol::readPort() {.........}; 

/***********************************************************************************/ 

class Device{ 

public: 

     Device(Protocol& port):_protocol(port){} 
     ~Device(); 
     virtual int getEvent(char *buffer) { return -1; } 
     int Device::selectBrand(); 

     .............. 

protected: 

     Protocol& _protocol; 

private: 

     int brand; 
     Device(const Device&orig); 
}; 

Device::~Device() {} 

int Device::selectBrand() { 

     ...... 

     switch (X) 

      case 1: 

        "use subclass Brand_B" 

      case 2: 

        "use subclass Brand_B" 

     ....... 

} 

/***********************************************************************************/ 

class Brand_A:public Device { 

public: 

     Brand_A(Protocol& port); 
     ~Brand_A(); 
     int getEvent(void *rawData); 

private: 

     Brand_A(const Brand_A&); 
}; 

Brand_A::Brand_A(Protocol& port):Device(port) {} 

Brand_A::~Brand_A() {} 

int Brand_A::getEvent(void *rawData) { 


      .... readPort(......); 

} 

/***********************************************************************************/ 

class Brand_B:public Device { 

public: 

     Brand_B(Protocol& port); 
     ~Brand_B(); 
     int getEvent(void *rawData); 

private: 

     Brand_B(const Brand_B&); 

}; 

Brand_B::Brand_B(Protocol& port):Device(port) {} 

Brand_B::~Brand_B() {} 

int Brand_B::getEvent(void *rawData) { 


      .... readPort(......); 

} 

/* main **********************************************************/ 

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

     Device *mydev; 

     char *buffer; 

    .............. 

    mydev->selectBrand(); 

    .......... 

    mydev->getEvent(buffer); 

    ........... 

} 
+0

예제에서 너무 많은 '....'섹션이 있습니다. 'selectBrand'가 실제로하는 일이 명확하지 않습니다 :'X'는 무엇이고 "use subclass"는 무엇을 의미합니까? – casablanca

+0

"선택"하여 서브 클래스를 "가져 오는"객체를 다운 캐스트하려는 경우, 그렇습니다. 접근 방식에 결함이 있습니다. 많은 코드를 제공하는 것이 혼란 스럽습니다. 핵심 클래스, 메소드 및 사용 방법은 어떨까요? – belwood

+0

'~ Device()'는 아마도'virtual'이어야합니다. – fredoverflow

답변

2

이것은 좋은 생각이 아니다.

일반적으로 대답은 dynamic_cast이지만 기본 클래스에서 자손의 특정 동작을 호출하는 것은 대개 잘못된 디자인 신호입니다.

클래스 계층 구조를 반전하고 템플릿을 사용해 볼 수 있습니다.

0

C++이이를 수행 할 때 다형성과 같은 것을 구현하려고하는 것처럼 보입니다. 기본 클래스에서 가상 메서드를 정의하고 하위 클래스에서이를 재정의하는 경우 포인터에 대한 메서드 또는 기본 형식에 대한 호출을 호출하면 하위 클래스의 구현이 호출됩니다. 예를 들어

:

당신은 당신이 그것을 만들 때 인스턴스가 파생 된 유형의 추가 기능을 가질 수 있도록 사용하려는 유형 (서브 클래스의 유형) 파생 것을 알고있다
class BaseClass 
{ 
    virtual void DoSomething() 
    { 
     printf("base"); 
    } 

}; 

class SubClass : public BaseClass 
{ 
    void DoSomething() 
    { 
     printf("sub"); 
    } 
}; 

int main() 
{ 
    BaseClass *myBase = new SubClass(); 
    myBase->DoSomething(); // should print "sub" to stdout 

    return 0; 
} 

. 그렇지 않다면 기본 클래스의 기능 만 있으면되고 기본 클래스 이외의 다른 것으로 처리 할 수 ​​없습니다 (기본 클래스가 상속하는 경우 상속 계층 구조 이상으로 처리 할 수 ​​없습니다).

실제로 다른 작업을 수행하지 않는 경우 다른 인스턴스를 구별하기 위해 멤버를 원할 수도 있습니다. 코드 예제에서 수행하려는 작업을 정확하게 설명하기는 어렵습니다. 어쩌면 당신이 성취하려고 시도하는 것보다 성취하려고하는 것에 대한 구체적인 예가 도움이 될 것입니다.

+0

내 문제는 내가 사용해야하는 하위 클래스를 모르는 주에 있습니다. 이것은 selectBrand라고하는 기본 클래스의 함수에 대한 수요입니다. 일부 검사를 기반으로 코드는 barnd_a 또는 brand_b 하위 클래스를 사용합니다. – Luke

+0

BaseClass * myBase = new SubClass(); 완벽한 것입니다 ....하지만 선택할 수있는 더 많은 하위 클래스가 있다면? – Luke

+0

두 번째 게시물을 읽은 후에 문제가 조금 더 나아 졌다고 생각합니다. 사용하는 클래스를 모르는 상태에서 기본 클래스에서 선언 된 여러 구현의 메소드를 사용하려는 경우 추상 팩토리 패턴이 필요할 수 있습니다. 뭔가가 : 장치 * 장치 = 장치 : : CreateDevice(); 여기서 Device는 장치의 일반적인 메서드를 선언하는 인터페이스 클래스이고 반환 된 인스턴스는 CreateDevice()로 결정된 특정 장치입니다. – ajmccluskey

0

제발, 내가 문제를 재구성하자. 하나의 baseClass와 일부 하위 클래스가 있습니다. Brand_A .... Brand_N

이제 main()에서 어떤 하위 클래스를 사용할 지 미리 알지 못합니다. 이 선택은 selectBrand라고하는 baseClass의 함수에 대해 요구됩니다. 필요한 것은 내부 조건을 기반으로 올바른 서브 클래스를 선택하고 사용하는 메커니즘입니다. 선택한 하위 클래스 main()에 가장하고 싶습니다. 이것을 얻는 방법?

1

내가 위에서 만든 의견을 분명히해야한다고 생각했습니다. 우선, abstract factory pattern에 대한 자세한 내용은 Wikipedia 페이지를 확인하십시오. 기본적으로 런타임에서 결정된 구현을 사용하여 인터페이스의 여러 구현에 액세스 할 수 있습니다. 그러나 인터페이스의 구현을 반환하는 팩토리 메서드에서 결정한대로 구현 내용을 알지 못합니다. 따라서 특정 구현이 아닌 인터페이스의 멤버 만 사용할 수 있습니다. 위의 클래스를 사용하는 예는 다음과 같습니다.

class Device 
{ 
    virtual int getEvent(void *rawData) = 0; 
} 

class BrandA : public Device 
{ 
    // define constructors/destructors etc. 

    int getEvent(void *rawData) 
    { 
     // BrandA's implementation for getEvent 
    } 
} 

class BrandB : public Device 
{ 
    // define constructors/destructors etc. 

    int getEvent(void *rawData) 
    { 
     // BrandB's implementation for getEvent 
    } 
} 

class DeviceFactory 
{ 
    static Device *CreateDevice(/*any parameters for determining the device?*/) 
    { 
     // You probably don't want to randomly determine which implementation you use... 
     if ((rand() % 2) == 0) 
     { 
      return new BrandA(); 
     } 
     else 
     { 
      return new BrandB(); 
     } 
    } 
} 

int main() 
{ 
    // CreateDevice will decide which type of device we use, however we can only 
    // explicitly reference the members of the base class (Device). 
    Device *myDevice = DeviceFactory::CreateDevice(); 

    myDevice->getEvent(); 

    return 0; 
} 
+0

예 - 질문의 요구 사항을 이해했다고 가정 할 때,이 질문에 대한 올바른 대답은 분명합니다. 특히 기본 클래스는 상속받은 클래스에 대해 아무것도 모릅니다. 항상 올바르게 작동한다는 신호입니다. – psmears

0

이 코드를 구현하고 테스트했습니다. 그것은 잘 작동합니다. 좋은 디자인인가요, 더 잘할 수 있습니까?

class BehaviorBase 
{ 
public: 
    virtual ~BehaviorBase() {} 
    virtual void DoSomethingOn(Object* obj) {} 
}; 

class Object 
{ 
public: 
    BehaviorBase* behavior; 
    void DoSomething(); 
    void ChangeBehavior(int param); 
    ~Object(); 
} 

class BehaviorA: public BehaviorBase 
{ 
    void DoSomethingOn(Object* obj) 
    { 
    printf("Behavior A\n"); 
    } 
}; 

class BehaviorB: public BehaviorBase 
{ 
    string other_data; 
    void DoSomethingOn(Object* obj) 
    { 
    printf("Behavior B\n"); 
    } 
}; 

void Object::DoSomething() 
{ 
    behavior->DoSomethingOn(this); 
} 

Object::~Object() 
{ 
    delete behavior; 
} 

void Object::ChangeBehavior(int param) 
{ 
    delete behavior; 
    switch(param) 
    { 
     case 1: behavior = new BehaviorA; break; 
     case 2: behavior = new BehaviorB; break; 
    } 
}  

int main(int argc, char **argv) { 
    int param=1; 
    Object *obj; 
    obj= new Object; 

    obj->ChangeBehavior(param); 
    obj->DoSomething();  
    delete obj; 
    return(0); 
} 
관련 문제