不能声明为抽象类型

时间:2014-07-09 16:14:06

标签: c++ inheritance virtual abstract pure-virtual

我收到以下错误:

error: cannot declare variable 'b' to be of abstract type 'B'
note: because the following virtual functions are pure within 'B'
note: virtual bool Serializable::eq(const QString&) const
      virtual bool eq( const QString & qs) const = 0;
                   ^
note: virtual bool Serializable::eq(const Serializable*) const
      virtual bool eq( const Serializable * o) const = 0;
                   ^

关于此代码:

class Serializable {
public:
    virtual  bool eq( const QString & qs) const = 0;
    virtual  bool eq( const Serializable * o) const = 0;
};

class JSONSerializable : public Serializable {
public:
    virtual  QString toJSON( void) const = 0;

    virtual  bool eq( const QString & qs) const {
                 return toJSON() == qs;
             }
    virtual  bool eq( const Serializable * o) const {
                 return eq( (( JSONSerializable *) o)->toJSON());
             }
};

class A : public Serializable {  };

class B : public A,
          public JSONSerializable {
public:
    virtual  QString toJSON( void) const {
                 return QString( "test!");
             }
};

…
B b;
qDebug() << b.toJSON();
…

我理解这是因为纯虚方法或/和多重继承。这个错误真的让我哭了。我怎么能让它消失?我非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

问题是B两次继承抽象类Serializable

  • 通过其基类A
  • 再次通过其他基类JSONSerializable

结果,您必须两次覆盖Serializable的两个纯虚拟。

由于您在询问有关B剩余摘要的问题,我的理解是您并不打算这样做:您希望B仅继承Serializable一次,好像它是一个接口,并使用JSONSerializable的实现来“混合”其他功能。如果是这种情况,您需要继承Serializable 虚拟,如下所示:

class Serializable {
public:
    virtual  bool eq( const QString & qs) const = 0;
    virtual  bool eq( const Serializable * o) const = 0;
};

class JSONSerializable : virtual public Serializable {
public:
    virtual  QString toJSON( void) const = 0;

    virtual  bool eq( const string & qs) const {
                 return toJSON() == qs;
             }
    virtual  bool eq( const Serializable * o) const {
                 return eq(dynamic_cast<const JSONSerializable*>(o)->toJSON());
             }
};

class A : virtual public Serializable {  };

class B : virtual public A,
          public JSONSerializable {
public:
    virtual  QString toJSON( void) const {
                 return QString( "test!");
             }
};

添加的virtual关键字指示编译器您只希望将Serializable个基数的一个“副本”包含在您的班级B中。

此更改解决了问题(demo)。