2017-03-06 7 views
1

정수 또는 문자열을 인수로 취할 수있는 getName 메서드가 있어야하는 기본 클래스 A가 있다고 가정 해 보겠습니다. 그래서 내가 만들 :C++에서 여러 인수 형식을 사용하는 가상 메서드

virtual string getName(int index) = 0; 
virtual string getName(string key) = 0; 

는 지금, 나는 두 개의 서로 다른 서브 클래스의 B를 만들려면 및 C. B 만 getName(int index) 필요로하고 C 만 getName(string key)이 필요합니다. 그러나 두 하위 클래스에서 두 메서드를 모두 덮어 쓰지 않으면 오류가 발생합니다. 하지만 내가 이렇게하면 B와 C는 다른 경우가 필요 없기 때문에 빈 방법을 사용하게 될 것입니다. getName

이 문제를 어떻게 극복 할 수 있습니까? 단순히으로

+0

대신 이름을 붙여 넣기의 템플릿을 사용하여 비토리오 로미오의 솔루션과 동일 템플릿 getName에 int 또는 string 매개 변수를 지원하는지 여부를 알 수 있습니까? – marcinj

+0

@AlexandreTHOUVENIN 의심 스럽지만 정의가 'int'와'string' 유형 모두에서 동일하지 않아야합니다. – George

+0

'A'의 사용 예제를 추가 할 수 있습니까? 같은 기본 클래스에서 두 getName 과부하가 필요한 이유는 무엇입니까? –

답변

-2

그들이 순수 가상하지만 단지 가상 제작하지 않습니다 getName(int)을 지원 하나 getName(string)을 지원 하나 : 당신은 실제로 두 개의 서로 다른 인터페이스를 원하는처럼

struct Blub 
{ 
    virtual void do1() {} // default definition 
    virtual void do2() = 0; //has to be overridden 
}; 
+0

OP는 파생 클래스에 정의 된 두 메서드 중 적어도 하나를 원합니다. – Nyashes

3

그것은 소리.

struct GetNameInt { 
    virtual string getName(int index) = 0; 
}; 

struct GetNameStr { 
    virtual string getName(string key) = 0; 
}; 

struct B : GetNameInt { /* ... */ }; 
struct C : GetNameStr { /* ... */ }; 

당신은 정말은 동일한 인터페이스를 하나의 기본 클래스를 필요로하고 은 당신이이 string 또는 int, 당신이 할 수 있습니다해야합니다 여부를 런타임에서 알고있는 경우 std::variant :

struct GetName { 
    virtual string getName(std::variant<int, string>) = 0; 
}; 
1

당신은 상속을 제대로 사용하지 않습니다. SOLID principles에 대해 더 자세히 읽으시기 바랍니다.

class A { 
//does not define neither of the getName methods 
} 

class Aa { 
    virtual string getName(int index) = 0; 
} 

class Ab { 
    virtual string getName(string key) = 0; 
} 

class B : A, Aa { 
    //inherits from A and defines string getName(int index) 
} 

class C : A, Ab { 
    //inherits from A and defines string getName(string key) 
} 
0

확인 : AA와 같은 Ab의, 금주 모임은 대한 getName (INT 지수) 개최 것이며, getName (문자열 키)를했을 경우 -

당신은 두 개의 클래스 (인터페이스)에 클래스 A를 분할해야 최고의 나는 시간 체크를 여전히 몇 가지 유형의 안전을 유지하면서 B와 C 사이에 공통의 부모를 유지하고 컴파일 가지고 올 수 :이 솔루션은 표준 OOP 솔루션하지만 템플릿 솔루션 아니라고

struct CommonA //protect this if possible 
{ 
    template<class type> 
    string getGenericName(type index); 
    virtual ~CommonA() {} 
}; 

template<class indexType> 
struct A : CommonA 
{ 
    virtual string getName(indexType index) = 0; 
}; 

struct B : A<int> 
{ 
    string getName(int index) override {cout << index << "\n"; } 
}; 
struct C : A<string> 
{ 
    string getName(string index) override {cout << index << "\n"; } 
}; 

template<class type> 
string CommonA::getGenericName(type index) 
{ 
    cout << "generic call: \n"; 
    return dynamic_cast<A<type>*>(this)->getName(index); 
} 

int main() 
{ 
    CommonA b = B(); 
    CommonA c = C(); 
    b.getGenericName(1); 
    c.getGenericName(string("hello world")); 
} 

참고.

편집은 내는 <가> 클래스는 당신이 당신의 기본 인터페이스를 사용하여, 당신의 클래스 B와 C 사용하면, 방법 (이름 붙여 넣기 악)

+0

가상 소멸자를'CommonA'에 넣고 더 나은 형식 안전성을 위해'static_cast' 대신'dynamic_cast'를 사용합니다. – Jarod42

+0

@ Jarod42 완료, 개선의 다른 방을 발견하면 더 편집 할 자유롭게 – Nyashes

+0

나에게 과장된 보입니다. 내 의견으로는 적어도 템플릿과 상속을 혼합하는 것이 좋지 않습니다. – zett42