2010-04-13 2 views
3

을에 조건을 적용 :C++ 나는 다음과 같은 추상 기본 클래스 X를 정의하고 적용하고자하는 상속 클래스

가) X에서 상속 모든 콘크리트 클래스 Y 생성자 Y (INT의 X를 정의)

b) 두 개의 Y 객체가 동일한 지 여부를 테스트 할 수 있어야합니다.

에 대한 좋은 해결책 중 하나는 구체적인 클래스가 정의해야 할 X 에 순수 가상의 fromInt 메소드를 넣는 것입니다. 그러나 나는 건설을 강요 할 수 없다.

B에 대한

), 나는 재정의 수업이 정의되지 않은 남아 있기 때문에 X

bool operator == (const X& other) const =0;

에 순수 가상 방법을 사용할 수없는 것. 이 유형이 일치하지 않기 때문에

bool operator == (const Y& other) const { //stuff}

를 정의하는 것만으로는 충분하지 않습니다. 이러한 문제를 어떻게 해결할 수 있습니까?

+1

왜 파생 형 생성자가 어떤 모양인지 신경 써야합니까? 또는 그들이 평등 함수를 정의하는지 여부? 어딘가에 (어딘가에 어떤 템플리트를 사용하고 있다면) 그 시점에서 컴파일이 실패합니다. 당신이 그 (것)들을 그 후에 사용하지 않는 경우에 그런 필요 조건 없습니다. 당신이 생성자를 polymorphicaly 나'operator =='정말로 사용할 수 없다는 것에주의하십시오. (가상 연산자 '='는 당신이 원하는 것을 거의하지 않을 것입니다) –

답변

3

no 인수 생성자를 private으로 만들고 기본 클래스에 public 단일 int 인수 생성자를 사용하여 강제로 생성 할 수 있습니다. 기본 클래스가 순수 가상 메소드를 가지고있는 한, 서브 클래스는 해당 생성자를 호출해야합니다.

은 운영자 ==에 관해서는, 당신의 서브 클래스의 모두

bool operator == (const BaseClass& other) const { .. };

을 정의하려고합니다. 최악의 경우, 기반에서 순수 가상 인 public equals (const BaseClass &) 메소드를 정의 할 수 있습니다.

EDIT : 강제 생성자가 완전히 사실이 아닙니다. 내가 제안한 것은 하위 클래스가 단일 인수 생성자를 호출하도록 강제합니다. 그들은 생성자에서 상수까지 상수를 전달하는 인자없는 생성자를 가질 수 있습니다.

+0

평등 연산자 ==에 대해서 do not let this do 같은 물건 Y y; Zz; (여기서 Y와 Z는 X로부터 상속 받는다) 내가 할 때 (y == z),이 테스트는 허용 될 것이다. – user231536

+0

작동해야합니다. 시도해보고 다음을 확인하십시오. –

+0

@ user231536 - 어떻게 그런 일을 할 수 있습니까? == 두 피연산자가 같은 유형이 아닌 경우 '동등'의 합리적인 정의에서 동일하지 않습니다. –

0

- 모든 사용자 코드에서 상속해야하는 CRTP와 중개자, 친구, 템플릿 하위 클래스를 사용하는 경우 가능해야합니다. 다음과 같은 것 :


struct X 
{ 
    virtual bool compare(X const&) const = 0; 
private: 
    X(); 

    template < typename T > 
    friend struct client_base; // don't recall the correct code here. 
}; 


template < typename Sub > 
struct client_base : X 
{ 
    // use boost::concepts to verify Sub has Sub(int) 
    Sub() : X() {} 
}; 

struct Y : client_base<Y> 
{ 
    Y(int); 

    bool compare(X const& x) 
    { 
    if ((Y* other = dynamic_cast<Y*>(x)) && *other == *this) return true; 
    return false; 
    } 
}; 

분명히 나는 ​​이것을 완전한 해결책으로 만들기 위해 많은 것을 남겨 두었습니다.

0

은) 나에게로 감각이없는하지만 당신은) 뭔가 나에 대한

template< typename T > 
Base* create(int x) 
{ 
    return T::create(x); 
} 

를 만들 C에서 "멀티 방법"구현 ++ B의 경우

2

), 당신이 할 수있는 Google에 요청할 수 있습니다

비교에서 매개 변수로 사용할 수없는 YS는 자동으로 Xs에 캐스팅 된 다음 dynamic_cast를 사용하여 비교할 수있는 클래스인지 확인할 수 있습니다.

2

쉬운 해결책이 있습니다.

// Class X 
// (... some documentation ...) 
// 
// ** NOTE: All subclasses of X must have a constructor that takes a single int, 
// ** and overload operator==. 

class X { 
... 
+2

진지하게. 특정 작업을 수행하기 위해 하위 클래스를 필요로하는 디자인은 잘못된 디자인입니다. +1 –

0

정수에서 구성 가능하도록 강제하는 것은 의미가 없습니다. 각 파생 클래스는 원하는대로 생성자를 자유롭게 정의 할 수 있습니다. 그러나 기본 클래스에 정수를 전달하도록 강제 할 수 있습니다 ... 어쨌든 훨씬 더 의미가 없습니다.

operator==, 당신은 그러나 그것의 본질을 얻을 수도 뒤틀린입니다 :

class Base 
{ 
public: 
    bool operator==(const Base& rhs) const; 
    bool operator!=(const Base& rhs) const { return !(*this == rhs); } 

private: 
    virtual bool equals(const Base& rhs) const = 0; // will pass only objects 
                // of the same dynamic type 
}; 

bool Base::operator==(const Base& rhs) const 
{ 
    return typeid(*this) == typeid(rhs) && this->equals(rhs); 
} 

bool Derived::equals(const Base& rhs) const // We KNOW Base is actually a Derived 
{ 
    return *this == static_cast<const Derived&>(rhs); 
} 

당신은 시도하고 사용하는 템플릿과 CRTP에 의해 그것을 조금 싸게 치장 할 수 있지만 Derived 경우에서 무엇을 상속를? 그것은지지 않을 것이다.