Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unresolved External (abstract class constructor/destructor)

So, I have an abstract class Panel and an implementation of it MyPanel. They look similar to this:

class Panel : public QWidget
{
public:
  Panel(QWidget* parent = 0) = 0;
  virtual ~Panel() = 0;
  // but wait, there's more!!
};

class MyPanel : public Panel
{
public:
  MyPanel(QWidget* parent = 0);
  ~MyPanel() {}; // nothing to do here
};

MyPanel::MyPanel(QWidget* parent) :
  Panel(parent)
{
  // you must construct additional pylons
}

I'm getting linker errors for the constructor/destructor from VC++

error LNK2019: unresolved external symbol "public: virtual __thiscall Panel::~Panel(void)" (??1Panel@@UAE@XZ) referenced in function "public: virtual __thiscall MyPanel::~MyPanel(void)" (??1MyPanel@@UAE@XZ)  mypanel.obj
error LNK2019: unresolved external symbol "public: __thiscall Panel::Panel(class QWidget *)" (??0Panel@@QAE@PAVQWidget@@@Z) referenced in function "public: __thiscall MyPanel::MyPanel(class QWidget *)" (??0MyPanel@@QAE@PAVQWidget@@@Z)  mypanel.obj

Why am I getting this linker error?


--- THE ANSWER ---

class Panel : public QWidget
{
public:
  Panel(QWidget* parent = 0) : QWidget(parent) {};
  virtual ~Panel() {};
  // but wait, there's more!!
};

I thought I had tried this before lunch. Turns out I was wrong.

like image 907
Corey D Avatar asked Aug 19 '09 17:08

Corey D


2 Answers

  1. there is no such thing like virtual constructor.
  2. You still should provide implementation of destructor.
like image 115
Artyom Avatar answered Nov 01 '22 21:11

Artyom


Purely virtual destructors still need to have an implementation.

To expand on that a bit:

The destructor of a class will always be called if any instance of a subclass gets destructed, so it needs to have an implementation. (Basically the only effect of making a destructor purely virtual is that it prevents instanatiation of the class).

As for the constructor: You're making it purely virtual (which I don't see any reason for doing), but then you explicitly call it from the subclass's constructor.

like image 30
sepp2k Avatar answered Nov 01 '22 19:11

sepp2k