多继承纯基函数

时间:2014-04-26 18:58:57

标签: c++ class inheritance multiple-inheritance pure-virtual

为什么这不起作用?虚函数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;

2 个答案:

答案 0 :(得分:0)

OpAdd<>是继承BinaryOp<>,也是Operator<>,它们都是抽象的。如果删除不必要且不明确的后继继承,它应该编译。

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

另一种方法,也就是避免定义Operator<>::Prec()的最佳方法,就是将您的继承设置为Op<>虚拟,例如live demo

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

答案 1 :(得分:0)

错误消息确切地告诉您问题是什么 - 通过GetNOperands Operator<T>基础继承的AddOp<T>方法是抽象的。由于这是BinaryOp<T>基础的不同基础(有两个不同的Op<T>基础彼此无关),因此该函数在基类的另一个实例中定义是无关紧要的。

您有两种解决方法:

  1. 创建所有公共基类virtual,以便它们引用相同的基本实例,而不是每次继承时创建新实例。这使得继承以合理的方式工作(它如何在任何其他语言中工作)

  2. 仅使用单一继承 - 每个类只能从一个基类继承(直接)。这样可以避免生成多个基类实例。