2012-07-26 3 views
1

내 문제를 사용하여 파생 클래스의 정보에 액세스하면 다음과 같다 :문제적인 디자인 개질시키기는/기본 오브젝트

int main() 
{ 
    Base* derivedobject = new Derived1(); 
    derivedobject->GetProperties()-> ??? 

return 0; 
} 

//******************** 
// BaseClass.h 
//******************** 
struct PropertyStruct 
{ 
    int x; 
}; 

class Base 
{ 
public: 
    Base(); 
    ~Base(); 

    virtual PropertyStruct GetProperties() = 0; 

private: 
}; 

//******************** 
// DerivedClass1.h 
//******************** 
struct PropertyStruct 
{ 
    int y; 
}; 

class Derived1 : public Base 
{ 
public: 
    Derived1(); 
    ~Derived1(); 

    PropertyStruct GetProperties() { return myOwnDifferentProperties; }; 

private: 

}; 

//******************** 
// DerivedClass2.h 
//******************** 
struct PropertyStruct 
{ 
    float z; 
}; 

class Derived2 : public Base 
{ 
public: 
    Derived2(); 
    ~Derived2(); 

    PropertyStruct GetProperties() { return myOwnDifferentProperties }; 

private: 

}; 

나는 PropertyStruct이 재정의하지 않다는 오류가 발생거야 그런 식으로 할 경우 . 네임 스페이스를 사용하거나 파생 클래스 내부에서 구조체의 이름을 바꾼다면 반환 형식이 Base에 정의 된 것과 같지 않다는 오류가 발생합니다. 가상 함수 반환 형식을 컴파일하는 포인터로 정의하면 기본 메서드 (이 예제에서는)에서 "GetProperties"함수에 액세스 할 때의 기본 문제는 파생 된 구조체 안에 어떤 변수가 있는지 알지 못합니다 수업.

이것을 실현할 수있는 방법이 있습니까? 파생 된 각 객체의 다양한 속성을 가져올 수 있지만 기본 클래스 객체를 사용할 수 있습니까?

+0

두 개의 'PropertyStruct'사이에 서로 다른 이름으로 기본 파생 관계를 설정할 수 있습니다. – iammilind

답변

0

템플릿 기능이 가상 일 수 없으므로 속성 계층 구조를 사용할 수 있습니다. 그것은 한 가지 방법 일 뿐이며 다른 방법은 없습니다. 파생 된 특성의 요소를 얻으려면 가상 게터 기능을 사용해야합니다.

struct BaseProp 
{ 
    virtual ~BaseProp() { } 
    virtual boost::any getProperty() const = 0; 
}; 

struct PropertyStruct : BaseProp 
{ 
    boost::any getProperty() const { return x; } 
private: 
    int x; 
}; 

struct PropertyStruct2 : BaseProp 
{ 
    boost::any getProperty() const { return y; } 
private: 
    float y; 
}; 

class Base 
{ 
public: 
    virtual std::shared_ptr<BaseProp> GetProperties() const = 0; 
    virtual ~Base() { } 
} 

class Derived 
{ 
public: 
    std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct(); } 
}; 

class Derived2 
{ 
public: 
    std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct2(); } 
}; 
+0

"다른 방법 없음"... 정말요? –

+0

@ Code-Guru 파생되지 않고 OP를 원하는 목표를 달성하는 다른 방법은 없습니다. – ForEveR

0
당신은 그렇게 할 템플릿 클래스를 사용할 수 있습니다

:

struct PropertyStruct1 { 
    float f; 
}; 

struct PropertyStruct2 { 
    int i; 
}; 

template<class T> 
class A{ 
public: 
    T GetProperties() {return mProps;} 

private: 
    T mProps; 
}; 

int main (int argc, const char * argv[]) { 

    A<PropertyStruct1> a1; 
    int f = a1.GetProperties().f; 
    A<PropertyStruct2> a2; 
    int i = a2.GetProperties().i; 
    return 0; 
} 
2

다른 언급했듯이, 여기 저기 목표를 달성 할 수있는 방법이 있지만 궁극적으로는 다음과 같이 코드를 작성하는 자신을 발견 할 것이다 :

Base * object = ...; 

    if object is Derived1 then 
     get Property1 and do something with it 
    else if object is Derived2 then 
     get Property2 and do something with it 

이것은 객체 지향 프로그래밍의 안티 패턴입니다. 다양한 파생 된 유형 간의 차이를 나타 내기 위해 이미 클래스 계층 구조가 있습니다. 개체에서 데이터를 추출하고 외부에서 처리하는 대신 가상 함수를 기본 클래스에 추가하고 파생 클래스가 처리를 수행하도록하는 것이 좋습니다. 는 파생 클래스에서 필요한 처리를 넣어 적절하지의 경우 (원치 않는 책임을 소개한다면 즉)

class Base 
{ 
public: 

    virtual void DoSomething() = 0; 
}; 

class Derived1 : Base 
{ 
public: 

    void DoSomething() 
    { 
     // use myOwnDifferentProperties as necessary 
    } 

private: 

    PropertyStruct myOwnDifferentProperties; 
}; 

는 당신은 당신의 계층 구조의 기능을 확장하는 방법으로 Visitor Pattern을 고려할 수 있습니다.

관련 문제