A problem with polymorphism

M

maxgross

Hi everyone,

ive got a problem with polymorphism. When i compile the code an error
occures:

error: 'class QtElement' has no member named 'DisplayQtElement'

I asked my friends and nobody could help me, all said it has to work.
I work with wxWidgets 2.6.3 under Linux.

Structure of classes:
wxTreeItemData->QtElement->StructureElement->Assessment
wxTreeItemData->QtElement->StructureElement->Section
wxTreeItemData->QtElement->QuestionElement->MultipleChoice
wxTreeItemData->QtElement->QuestionElement->MultipleResponse

QtElement, StructureElement, QuestionElement are abstract classes.

Here the code:
---------------------------------------------------------------------------------------------
#ifndef QT_ELEMENT_H_
#define QT_ELEMENT_H_
#include <wx/treectrl.h>

class QtElement: public wxTreeItemData
{
protected:
QtElement(NativeString title) :title(title) {}

NativeString title;

public:
virtual void DisplayQtElement() = 0;

virtual NativeString GetTitle() { return title; }

virtual ~QtElement() {}
};
#endif /*QT_ELEMENT_H_*/
---------------------------------------------------------------------------------------------
#ifndef QUESTION_ELEMENT_H_
#define QUESTION_ELEMENT_H_
#include "qt_element.h"

class QuestionElement : public QtElement
{
protected:
QuestionElement(NativeString title, NativeString qText)
: QtElement(title), questionText(qText) {}

NativeString questionText;
public:
virtual ~QuestionElement() {}

virtual NativeString GetQuestionText() { return questionText; }
};
#endif /*QUESTION_ELEMENT_H_*/
---------------------------------------------------------------------------------------------
#ifndef MULTIPLE_RESPONSE_H_
#define MULTIPLE_RESPONSE_H_
#include "question_element.h"
class MultipleResponse: public QuestionElement
{
public:
MultipleResponse(NativeString title, NativeString qText)
: QuestionElement("MultipleResponse", title, qText) {}

virtual ~MultipleResponse() {}

virtual void DisplayQtElement();

private:
};

inline void
MultipleResponse::DisplayQtElement()
{
// display element
}
#endif /*MULTIPLE_RESPONSE_H_*/
---------------------------------------------------------------------------------------------
Usage:
---------------------------------------------------------------------------------------------
....
wxTreeCtrl qtTree = new wxTreeCtrl(this, ID_TREE_CTRL,
wxDefaultPosition, wxSize(100,300),wxTR_SINGLE | wxTR_HIDE_ROOT |
wxTR_FULL_ROW_HIGHLIGHT | wxTR_HAS_BUTTONS);
QtElement *qe = new MultipleChoice(title,q_text);
qtTree->AppendItem(parent, title, -1, -1,
dynamic_cast<wxTreeItemData*>(qe));
....

QtElement *qt =
dynamic_cast<QtElement*>(qtTree->GetItemData(selection));
// if i cast to QuestionElement, StructureElement or the conrete
classes then it to works

qt->DisplayQtElement(); // error
qt->GetTitle(); // is working
---------------------------------------------------------------------------------------------
I have to derive QtElement from wxTreeItemData so that i can add a
QtElement to the wxTreeCtrl.

Perhaps someone can help me, thanks.
Max
 
J

Jim Langston

Hi everyone,

ive got a problem with polymorphism. When i compile the code an error
occures:

error: 'class QtElement' has no member named 'DisplayQtElement'

I asked my friends and nobody could help me, all said it has to work.
I work with wxWidgets 2.6.3 under Linux.

Structure of classes:
wxTreeItemData->QtElement->StructureElement->Assessment
wxTreeItemData->QtElement->StructureElement->Section
wxTreeItemData->QtElement->QuestionElement->MultipleChoice
wxTreeItemData->QtElement->QuestionElement->MultipleResponse

QtElement, StructureElement, QuestionElement are abstract classes.

Here the code:
---------------------------------------------------------------------------------------------
#ifndef QT_ELEMENT_H_
#define QT_ELEMENT_H_
#include <wx/treectrl.h>

class QtElement: public wxTreeItemData
{
protected:
QtElement(NativeString title) :title(title) {}

NativeString title;

public:
virtual void DisplayQtElement() = 0;

virtual NativeString GetTitle() { return title; }

virtual ~QtElement() {}
};
#endif /*QT_ELEMENT_H_*/
---------------------------------------------------------------------------------------------
#ifndef QUESTION_ELEMENT_H_
#define QUESTION_ELEMENT_H_
#include "qt_element.h"

class QuestionElement : public QtElement
{
protected:
QuestionElement(NativeString title, NativeString qText)
: QtElement(title), questionText(qText) {}

NativeString questionText;
public:
virtual ~QuestionElement() {}

virtual NativeString GetQuestionText() { return questionText; }
};
#endif /*QUESTION_ELEMENT_H_*/
---------------------------------------------------------------------------------------------
#ifndef MULTIPLE_RESPONSE_H_
#define MULTIPLE_RESPONSE_H_
#include "question_element.h"
class MultipleResponse: public QuestionElement
{
public:
MultipleResponse(NativeString title, NativeString qText)
: QuestionElement("MultipleResponse", title, qText) {}

virtual ~MultipleResponse() {}

virtual void DisplayQtElement();

private:
};

inline void
MultipleResponse::DisplayQtElement()
{
// display element
}
#endif /*MULTIPLE_RESPONSE_H_*/
---------------------------------------------------------------------------------------------
Usage:
---------------------------------------------------------------------------------------------
...
wxTreeCtrl qtTree = new wxTreeCtrl(this, ID_TREE_CTRL,
wxDefaultPosition, wxSize(100,300),wxTR_SINGLE | wxTR_HIDE_ROOT |
wxTR_FULL_ROW_HIGHLIGHT | wxTR_HAS_BUTTONS);
QtElement *qe = new MultipleChoice(title,q_text);
qtTree->AppendItem(parent, title, -1, -1,
dynamic_cast<wxTreeItemData*>(qe));
...

QtElement *qt =
dynamic_cast<QtElement*>(qtTree->GetItemData(selection));
// if i cast to QuestionElement, StructureElement or the conrete
classes then it to works

Of course. When you dynamic_cast it and assign it, the pointer is loosing
the polymorphic nature. You are saying, "Here is a pointer pointing to a
QtElement" and assigning it to qt. As far as qt, and your program, knows,
it IS a QtElement pointer. And the error is correct, QtElement has no
DisplayQtElement, because it's declared pure virtual.
 
K

kwikius

dynamic_cast<QtElement*>(qtTree->GetItemData(selection));
// if i cast to QuestionElement, StructureElement or the conrete
classes then it to works

qt->DisplayQtElement(); // error
qt->GetTitle(); // is working
---------------------------------------------------------------------------------------------
I have to derive QtElement from wxTreeItemData so that i can add a
QtElement to the wxTreeCtrl.

Perhaps someone can help me, thanks.
Max


AFAICS it should work, so it looks to me like a bug in the compiler.
Only thing I can suggest is providing some
body in the base class which either asserts or throws an exception if
actually invoked. (Based on the fact that GetTitle works). You could
make it conditional on the compiler version. The protected ctor should
prevent instantiation of QtElements.

regards
Andy Little
 
K

kwikius

Jim said:
Of course. When you dynamic_cast it and assign it, the pointer is loosing
the polymorphic nature. You are saying, "Here is a pointer pointing to a
QtElement" and assigning it to qt. As far as qt, and your program, knows,
it IS a QtElement pointer. And the error is correct, QtElement has no
DisplayQtElement, because it's declared pure virtual.

If that were the case (which it isnt) there would be no point in ABC's:
(IOW the following wouldnt work)

#include <iostream>

struct base{
virtual void f()const = 0;
virtual ~base(){}
};

struct derived : base{
void f()const {std::cout << "Hello\n";}
};

int main()
{
derived d;

base * b= 0;

// dynamic cast use for example only
b= dynamic_cast<base*>(&d);

b->f();
}
 
M

maxgross

Hi,

first thanks for your answers.

I solved the problem, it was an include problem. I included an old
version of the base class in another file.

mfg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top