0

I have the above described problem, but the cause is clearly somewhere else because this used to work before and i did not do any major changes except from minimalizing the includes and forward declarations of my project.

I have several classes, all derived from some QObjects and UIElementInterface. In the following example a QCheckBox

#ifndef CHECKBOX_H
#define CHECKBOX_H

#include <QCheckBox>
#include "uielementinterface.h"

#include <QString>

class QPoint;
class QSize;
class QWidget;

class CheckBox : public QCheckBox, public UIElementInterface
{
    Q_OBJECT
//...
public:
    CheckBox(const QString& label, const QString& define, const QString& header, const QPoint& pos, const QSize& size, QWidget *parent = 0);
};
#endif

and the UIElementInterface

#ifndef UIELEMENTINTERFACE_H
#define UIELEMENTINTERFACE_H

class UIElementInterface
{
public:
    virtual ~UIElementInterface(){}
    UIElementInterface(const QString& define, const QString& header);
    //...        
};
#endif

In XmlReader I forward declared CheckBox (and UIElementInterface). Here I pass in CheckBox* by pointer as its base UIElementInterface

void XmlReader::readCheckBox(ContainerInterface* container, const QString& header)
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "checkbox");
    QXmlStreamAttributes attr = xml.attributes();
    CheckBox* checkBox = container->createCheckBox(getLabel(attr), getDefine(attr), getHeader(attr, header), getTopLeft(attr), getSize(attr));
    m_centralWidget->setUIElement(getDefine(attr), checkBox); //<--Compiler Error, used to work fine.
    xml.readElementText();
}

I did some printing in CheckBox and UIElementInterface constructor to verify proper initialization of both.

Here is setUIElements implementation:

void CentralWidget::setUIElement(const QString& define, UIElementInterface* UIElement)
{
    m_uiElementMap[define] = UIElement;
}

Invoking this from XmlReader gives me:

error: no matching function for call to 'CentralWidget::setUIElement(QString, CheckBox*&)'

A static_cast from CheckBox to UIElementInterface would give an invalid static_cast error and an implicit cast will give me a cannot convert ... in initialization error.

Like i said, the same inheritance pattern used to work and as far as i know it is meant to work. So: What am i missing?

Thanks in advance.

EDIT

Here is the compiler output (for the call of setUIElement):

../src/xmlreader.cpp:278: error: no matching function for call to 'CentralWidget::setUIElement(QString, CheckBox*&)'
../include/centralwidget.h:40: note: candidates are: void CentralWidget::setUIElement(const QString&, UIElementInterface*)

And the class definition of CentralWidget

/*!
 * \class CentralWiget
 * \brief The CentralWidget class is a subclass ofQWidget.
 */
#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H

#include <QWidget>
#include "containerinterface.h"
#include <QMap>
#include <QString>

class QHBoxLayout;
class UIElementInterface;
class QPoint;
class QSize;
class PushButton;
class CheckBox;
class ComboBox;
class Image;
class Led;
class Text;
class TabWidget;
class QTabWidget;
class TreeWidget;

class CentralWidget : public QWidget, public ContainerInterface
{
    Q_OBJECT

private:
    QHBoxLayout* m_layout;
    QMap<QString, UIElementInterface*> m_uiElementMap;

public:
    CentralWidget(QWidget* parent = 0);

    ~CentralWidget();

    void setUIElement(const QString& define, UIElementInterface* UIElement);

    UIElementInterface* getUIElement(const QString& define);

    void createHorizontalLayout();

    void addWidgetToLayout(QWidget* widget);

    PushButton* createButton(const QString &label, const QString &define, const QPoint& topLeft, const QSize& size);

    CheckBox* createCheckBox(const QString &label, const QString &define, const QString &header, const QPoint& topLeft, const QSize& size);

    ComboBox* createComboBox(const QString &label, const QString &define, const QString &header, const QPoint& topLeft, const QSize& size);

    Image* createImage(const QString &file, const QString &define, const QPoint& topLeft, const QSize& size);

    Led* createLed(const QString &define, const QString &onColor, const QString &offColor, const QPoint& topLeft, const QSize& size);

    Text* createText(const QString &define, const QString &label, const QPoint& topLeft, const QSize& size);

    TabWidget* createTabWidget(const QPoint& topLeft, const QSize& size);

    TreeWidget* createTreeWidget(const QStringList& labels, const QPoint& topLeft, const QSize& size);

    void connectUIElement(const QString& signalName, const QString& slotName, UIElementInterface* UIElement);

private slots:
    void setDef(QString s);

    void sendCom(QString s);
};
#endif
`
tobilocker
  • 891
  • 8
  • 27

1 Answers1

-1

turn m_centralWidget->setUIElement(getDefine(attr), checkBox);

into

m_centralWidget->setUIElement(getDefine(attr), (UIElementInterface*)checkBox);

ar1a
  • 374
  • 3
  • 10
  • Wouldn't this resolve to a `reinterpret_cast`? – Rotem Apr 04 '16 at 08:08
  • Hello. This did not need any cast before, and afaik it sould not need by design. The error seems to be nested in my fwd declare and include pattern. – tobilocker Apr 04 '16 at 08:18
  • @tobilocker You can't forward declare inheritance. The compiler has no way of knowing that `CheckBox` inherits from `UIElementInterface` based on a forward declare. – Rotem Apr 04 '16 at 08:25
  • Thats it i need to include "checkbox.h" in "XmlReader" than it works. This is totally legit, but breaks the rule in my approach for including header files and forward declaring classes. – tobilocker Apr 04 '16 at 09:30