2014-04-26 3 views
0

왜 작동하지 않습니까? 가상 함수 GetNOperands()PerformOp()은 BinaryOp 클래스에 정의되어 있고 DoOp()은 OpAdd 클래스에 정의되어 있습니다. 연산자 클래스의 가상 Prec() 함수도 OpAdd에 정의되어 있습니다. 파생 클래스의 각 함수에 대한 정의가 하나뿐이므로이 코드에 적용되지 않는다고 생각하는 "다이아몬드 문제"를 조사했습니다.다중 상속 순수 기본 함수

#include <iostream> 
#include <vector> 
#define PREC_LOW 0 
#include <assert.h> 

//operator class - abstract 
template <class T> class Op { 
public: 
    virtual unsigned int GetNOperands() = 0; 
    virtual bool PerformOp(std::vector<T>& operands, T& result) = 0; 
    virtual ~Op() {} 
}; 

//binary operator class - for 2 operators - abstract 
template <class T> class BinaryOp : public Op<T> { 
public: 
    unsigned int GetNOperands(); 
    bool PerformOp( std::vector<T>& operands, T& result); 
    virtual ~BinaryOp() {} 
protected: 
    virtual bool DoOp(T first, T second, T& result) = 0; 
}; 

template <class T> class Operator : public Op<T> { 
public: 
    virtual unsigned int Prec() = 0; //precedence 
}; 

template <class T> class OpAdd : public BinaryOp<T>, public Operator<T> { 
public: 
    unsigned int Prec(); 
private: 
    bool DoOp(T first, T second, T& result); 
}; 

template <class T> unsigned int BinaryOp<T>::GetNOperands() { 
    return 2; 
} 
template <class T> bool BinaryOp<T>::PerformOp( std::vector<T>& operands, T& result) { 
    assert(operands.size() == 2); 
    return DoOp(operands.at(0),operands.at(1),result); 
} 
template <class T> bool OpAdd<T>::DoOp(T first, T second, T& result) { 
    result = first + second; 
    return true; 
} 
template <class T> unsigned int OpAdd<T>::Prec() { 
    return PREC_LOW; 
} 

int main() { 
    OpAdd<int> a; 
    return 0; 
} 

편집 : 컴파일러 오류 상태 :

source.cpp: In function 'int main()': 
source.cpp:55:13: error: cannot declare variable 'a' to be of abstract type 'OpAdd<int>' 
    OpAdd<int> a; 
      ^
source.cpp:30:29: note: because the following virtual functions are pure withi 
n 'OpAdd<int>': 
template <typename T> class OpAdd : public BinaryOp<T>, public Operator<T> { 
          ^
source.cpp:10:23: note:   unsigned int Op<T>::GetNOperands() [with T = int] 
    virtual unsigned int GetNOperands() = 0; 
        ^
source.cpp:11:15: note:   bool Op<T>::PerformOp(std::vector<T>&, T&) [with T = int] 
    virtual bool PerformOp(std::vector<T>& operands, T& result) = 0; 
+0

"작동하지 않음"을 정의하십시오. –

+2

자, 'OpAdd'에서 * 직접 * 기본 클래스'Operator '(및 기본 클래스)의 가상 함수를 재정의하지 않았습니다. – dyp

+0

나는 컴파일 오류 – joelyboy94

답변

0

OpAdd<>BinaryOp<>을 inherithing뿐만 아니라 Operator<>되어, 모두 추상적 여기에 코드입니다. 불필요하고 애매한 후자의 상속을 제거하면 컴파일해야합니다.

template <class T> class OpAdd : public BinaryOp<T> { 
public: 
    unsigned int Prec(); 
private: 
    bool DoOp(T first, T second, T& result); 
}; 

아마도 Operator<>::Prec()live demo처럼 Op<> 가상으로 상속을 설정하는 것입니다 또한 정의 피할 수있는 최선의 하나입니다 또 다른 방법.

template <class T> class BinaryOp : public virtual Op<T> 
... 
template <class T> class Operator : public virtual Op<T> 
.... 
0

오류 메시지가 문제가 정확히 무엇을 알려줍니다 - AddOp<T>Operator<T>베이스를 통해 상속 GetNOperands 방법은 추상적이다. 이것은 BinaryOp<T>베이스 (서로 아무 관계가없는 두 개의 다른 Op<T> 개의베이스가 있음)와 구별되는 기초이기 때문에 함수가 기본 클래스의 다른 인스턴스에 정의되어 있다는 사실은 부적합합니다. 그들은 새로운 인스턴스 당신이 상속마다 만드는 대신 동일한 기본 인스턴스를 참조하도록,

  1. virtual 모든 공용 기본 클래스 확인 :

    당신은이 문제를 해결하는 방법의 두 가지 선택이있다. 이로 인해 상속은 합리적인 방법으로 작동합니다 (다른 언어로 작동하는 방법)

  2. 각 클래스는 하나의 기본에서만 상속 가능합니다. 이렇게하면 기본 클래스의 인스턴스를 여러 개 생성하지 않아도됩니다.