C ++ Multiple Inheritance with Interfaces?

Greetings to all

I come from the Java background, and I am having difficulty with multiple inheritance.

I have an interface called IView that has an init () method. I want to get a new class called PlaneViewer that implements the above interface and extends another class. (QWidget).

My implementation is as follows:

IViwer.h (header file only, not CPP file):

#ifndef IVIEWER_H_ #define IVIEWER_H_ class IViewer { public: //IViewer(); ///virtual //~IViewer(); virtual void init()=0; }; #endif /* IVIEWER_H_ */ 

My derived class.

PlaneViewer.h

 #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

 #include "planeviewer.h" PlaneViewer::PlaneViewer(QWidget *parent) : QWidget(parent) { ui.setupUi(this); } PlaneViewer::~PlaneViewer() { } void PlaneViewer::init(){ } 

My questions:

  • Do I need to declare the init () method in the PlaneViewer interface, because it is already defined in IView?

2. I cannot execute the code above, give an error:

PlaneViewer] + 0x28): undefined reference to `typeinfo for IViewer 'collect2: ld returned 1 exit status

Should I have an implementation for IView in a CPP file (because all I want is an interface, not an implementation)?

+6
c ++ inheritance multiple-inheritance virtual
source share
6 answers

Do I need to declare the init () method in the PlaneViewer interface, because it is already defined in IView?

You do not need to declare init () in the PlaneViewer, but if you are not, the PlaneViewer will be an abstract class, which means you cannot create one.

If you want to ask if you need to have void init (); in the header file for PlaneViewer and in the .cpp file. The answer is yes.

I cannot execute the code above, give an error: PlaneViewer] + 0x28): undefined reference to `typeinfo for IViewer 'collect2: ld returned 1 exit status

I think that either you are not building the same code, or your compilation command is incorrect.

I removed the QT stuff and was able to correctly create the code using g ++.

The error means that the IViewer class was not found by the linker.

I get this error if I remove the '= 0' part that makes "IViewer :: init ()" a pure virtual function. You may also get this error if you uncomment the constructor and / or destructor in IViewer.

Should I have an implementation for IView in a CPP file?

Not. C ++ doesn't care if it is in a .cpp file or a .h file. Unlike Java, the C / C ++ preprocessor first resolves all incoming messages and generates a single file containing all the code. He then passes this to the C / C ++ compiler. In fact, you can enable .cpp if you want. Not a good idea.

+3
source share

A good way to think about interface classes is that they determine which methods derived classes SHOULD implement.

Do I need to declare the init () method in the PlaneViewer interface as well because it is already defined in IView?

Quick answer: yes, you must implement the init method in IViewer , because in the base class the method is declared as pure virtual. This means that any derived class MUST provide its own implementation of this method, since there is no base class method.

2. I cannot execute the code above, give an error:

PlaneViewer] + 0x28): undefinedlink to `typeinfo for IViewer 'collect2: ld returned 1 exit status

This is a g ++ compiler error, which indicates (as indicated above) that you have a derived class from a base that has a pure virtual function, and that the derived class does not implement a pure virtual method, as it should.

Oh, and it should also be noted that you have no problem with multiple inheritance, the problem will exist if only IViewer and PlaneViewer are involved.

+7
source share

Yes, you must declare init in your PlaneViewer . If you didn’t do this, then init would not exist in PlaneViewer , and PlaneViewer would still be considered abstract (because there is no init implementation).

You need to define empty bodies for your (virtual) destructor in IViewer . C ++ “interfaces” are not really interfaces, but only by convention do you create a class with all pure virtual methods and no fields: however, they are still “normal” classes from the point of view of the compiler, so you still need to provide a destructor implementation .

 class IViewer { public: IViewer() { } virtual ~IViewer() { } virtual void init() = 0; }; 
+4
source share

The typeinfo problem is caused by the lack of a destructor implementation for the IViewer class. Typically, compilers will generate internal data structures (for example, "typeinfo") along with a virtual destructor.

You need to compile and link the file containing:

 #include "iviewer.h" IViewer::~IViewer() { } 

A virtual destructor is good practice, because it gives the compiler a compilation unit for using RTTI information, and also allows the delete operator to work correctly when calling the base class pointer.

Others will answer the question with the init () method, but in the end: if you are going to implement it in PlaneViewer, you need to declare it.

+3
source share

Yes, you need to re-declare virtual void init() in a subclass and implement it, because IViewer declares a pure virtual function.

See another question for an explanation of your error. This is caused by the declaration of a virtual function (not pure) and not defining it. This is not obvious from the code you posted, so I suspect you might have obsolete object files that were not restored (you commented out the IViewer constructor and virtual destructor).

As an additional note, you should provide virtual destructors with an empty body for your interfaces .

+2
source share

I did a lot of work in both languages, and there is a cutting cookie template that you can usually use to turn the Java interface into a C ++ interface:

// Let's start with the Java interface

 interface Numeric { public int toInteger(); public double toDouble(); }; 

C ++ precedes Java and does not require the definition of the special "interface" keyword for pure virtual classes. So you really need to do some work that the Java compiler does:

// Equivalent C ++ Class

 class Numeric { private: Numeric(const Numeric&); Numeric& operator=(const Numeric&); public: Numeric() {} virtual ~Numeric() {} virtual int toInteger() = 0; virtual double toDouble() = 0; }; 

Another good rule to follow in C ++ is that whenever you inherit a base class using pure virtual methods, redeclare them in the derived class, even if you leave them as pure virtual ones. This will not hurt performance, and everyone knows that an object is only a partial implementation.

+2
source share

All Articles