首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有接口的C++多重继承?

具有接口的C++多重继承?
EN

Stack Overflow用户
提问于 2010-06-11 05:38:28
回答 6查看 19.5K关注 0票数 8

大家好,

我来自Java背景,在多重继承方面遇到了困难。

我有一个名为IView的接口,它有init()方法,我想派生一个名为PlaneViewer的新类,实现上述接口并扩展另一个类。(QWidget)。

我的执行情况如下:

IViwer.h (只有头文件,没有CPP文件) :

代码语言:javascript
复制
#ifndef IVIEWER_H_
#define IVIEWER_H_

class IViewer
{
public:
  //IViewer();
  ///virtual
  //~IViewer();
  virtual void init()=0;
};

#endif /* IVIEWER_H_ */

我的派生类。

PlaneViewer.h

代码语言:javascript
复制
#ifndef PLANEVIEWER_H
#define PLANEVIEWER_H

#include <QtGui/QWidget>
#include "ui_planeviewer.h"
#include "IViewer.h"
class PlaneViewer : public QWidget , public IViewer
{
    Q_OBJECT

public:
    PlaneViewer(QWidget *parent = 0);
    ~PlaneViewer();
    void init(); //do I have to define here also ?

private:
    Ui::PlaneViewerClass ui;
};

#endif // PLANEVIEWER_H

PlaneViewer.cpp

代码语言:javascript
复制
#include "planeviewer.h"

PlaneViewer::PlaneViewer(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

PlaneViewer::~PlaneViewer()
{

}

void PlaneViewer::init(){

}

我的问题是:

  1. 是否有必要在PlaneViewer接口中声明init()方法,因为它已经在IView中定义了?

2.我不能对以上代码进行修改,请给出错误:

PlaneViewer]+0x28):未定义的对“`typeinfo for IViewer”collect2: ld返回1个退出状态的引用

我是否必须在CPP文件中实现IView (因为我只想要一个接口,而不是作为实现)?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-06-11 06:02:27

是否有必要在PlaneViewer接口中声明init()方法,因为它已经在IView中定义了?

您不必在PlaneViewer中声明init(),但是如果不声明,PlaneViewer将是一个抽象类,这意味着您不能实例化它。

如果您想问是否必须在PlaneViewer的头文件和.cpp文件中有'void ();‘。答案是肯定的。

我无法完成上面的代码,给出错误: PlaneViewer]+0x28):对‘IViewer的`typeinfo’collect2的未定义引用: ld返回了1个退出状态

我认为您不是在构建相同的代码,就是编译命令不正确。

我去掉了QT的内容,并且能够很好地用g++构建代码。

此错误意味着链接器找不到IViewer类。

如果删除'=0‘部分,使'IViewer::init()’成为一个纯粹的虚拟函数,我就会得到这个错误。如果在IViewer中取消对构造函数和/或析构函数的注释,也会得到该错误。

我是否必须在CPP文件中实现IView?

不是的。C++不在乎它是在.cpp文件还是.h文件中。与Java不同,C/C++预处理程序首先解析所有包含的内容并生成一个包含所有代码的文件。然后将其传递给C/C++编译器。如果您愿意,实际上可以包括一个.cpp。不过不是个好主意。

票数 3
EN

Stack Overflow用户

发布于 2010-06-11 05:42:16

考虑接口类的一个好方法是,它们指定派生类必须实现的方法。

是否有必要在PlaneViewer接口中声明init()方法,因为它已经在IView中定义了?

快速回答是肯定的,您必须在IViewer中实现init方法,因为在基类中,该方法被声明为纯虚拟的。这意味着任何派生类都必须提供它自己的方法实现,因为没有实现基类方法。

2.我不能对以上代码进行修改,请给出错误: PlaneViewer]+0x28):未定义的对“`typeinfo for IViewer”collect2: ld返回1个退出状态的引用

这是一个g++编译器错误,它指示(如前所述)您有一个来自具有纯虚拟函数的基类的派生类,并且派生类没有实现纯虚拟方法,这是必须的。

哦,还应该注意到,您没有多重继承问题,如果只涉及IViewerPlaneViewer,问题仍然存在。

票数 8
EN

Stack Overflow用户

发布于 2010-06-11 05:47:02

是的,您也必须在您的init中声明PlaneViewer。如果没有,那么init就不存在于PlaneViewer中,PlaneViewer仍然被认为是抽象的(因为没有init的实现)。

您需要在IViewer中为(虚拟)析构函数定义空体。C++中的“接口”并不是真正的接口,只有按照约定才能创建一个包含所有纯虚拟方法而没有字段的类:但是,从编译器的角度来看,它们仍然只是“常规”类,所以仍然需要提供析构函数的实现。

代码语言:javascript
复制
class IViewer
{
public:
    IViewer() { }
    virtual ~IViewer() { }

    virtual void init() = 0;
};
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3020425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档