-1

I am trying to achieve something similar to what is explained here.

I have an Interface class defined as:

class IInterface
{
public:

    virtual bool foo() = 0;
    virtual void destroy() = 0;
}

And and implementation class defined as:

class MyImplementation : public IInterface
{
    MyImplementation();
    ~MyImplementation();

    virtual bool foo();
    virtual void destroy() {delete this;}

private:

    MyImplementation(MyImplementation const&);
    void operator=(MyImplementation const&);
}

extern "C" API MyInterface* __cdecl createMyImplementation();

This works fine in Release mode using VS2010, but in Debug mode, the compiler gives me this error:

MyImplementation.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall IInterface::IInterface(void)" (__imp_??0IInterface@@QAE@XZ) referenced in function "public: __thiscall MyImplementation::MyImplementation(void)" (??0MyImplementation@@QAE@XZ)

What is the problem and how can I fix this ?

From my understanding, we should not have virtual constructors... (see this question).

EDIT:

Fixed typo. foo does have a body, this is a simplified version of the real code.

Explanation of the why of the destroy function:

http://www.parashift.com/c++-faq-lite/delete-this.html

http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll

Community
  • 1
  • 1
Smash
  • 3,722
  • 4
  • 34
  • 54
  • 5
    Instead of you `destroy` member, you should probably have a `virtual` destructor. – 5gon12eder Sep 25 '14 at 19:19
  • Linker errors (like the one you are getting) are highly sensitive to the object file/library/DLL organization of your project. So far you provided no details about it. Describe it better. How are your declarations distributed across source files? – AnT stands with Russia Sep 25 '14 at 19:24
  • So while everyone is right about your pattern being awful, I don't think it should cause the error you're seeing....how are you including IInterface in MyImplementation? – IdeaHat Sep 25 '14 at 19:25
  • I don't see *anywhere* in the error message that it's hinting that you need a virtual constructor -- it's just saying that it can't find *any* constructor for the interface class. (Which is a bit weird, given that the lack of any user-defined constructor *should* result in an inline public default constructor...) – cdhowie Sep 25 '14 at 19:30
  • @NeilKirk I know this. I'm just confused at how OP made the (illogical) leap between that error message and the nonsensical term "virtual constructor." – cdhowie Sep 25 '14 at 19:41
  • Well it seems to be looking for `IInterface::IInterface(void)` which would be a virtual constructor no ? – Smash Sep 25 '14 at 20:19
  • @Smash no, C++ doesn't have virtual constructors. That is a default constructor – M.M Sep 25 '14 at 20:22
  • I think this error message is MSVC's equivalent of the g++ error "undefined reference to 'vtable for MyImplementation'" – M.M Sep 25 '14 at 20:28
  • You really do need to post *real code*. Remove anything irrelevant from the original code, and **verify that the problem still occurs**, then post the exact code causing the problem. – M.M Sep 25 '14 at 20:34

2 Answers2

2
virtual void destroy() {delete this};

What are you doing? Suiciding? Be careful!

In your case, MyImplementation::foo() needs to have a body (i.e. defined), that's why you are getting linker error

quantdev
  • 23,517
  • 5
  • 55
  • 88
Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69
  • 3
    False. `MyImplementation::foo()` was never mentioned in the linker error. – Gutblender Sep 25 '14 at 19:20
  • +1 And probably because the function is subject to dead code elimination, the bug is hidden in the release build. – 5gon12eder Sep 25 '14 at 19:21
  • I believe this is the correct answer. I [reproduce the error](http://ideone.com/CCsDKu) using GCC, and in accordance with [this thread](http://stackoverflow.com/questions/3065154/undefined-reference-to-vtable) , defining an empty body for `virtual bool foo() {}` fixed the error. – M.M Sep 25 '14 at 20:28
  • Sorry for this being a simplified version of the code. Will verify if every function in the class has a body. – Smash Sep 25 '14 at 20:30
  • As for the `destroy`, I was referring to this http://www.parashift.com/c++-faq-lite/delete-this.html, from here http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll – Smash Sep 25 '14 at 22:11
1

It seems to be that your problem is that you aren't including the IInterface.obj file in the link. In release mode, the compiler realizes that the ctor is vacuous and removes calls to it. But it debug mode (for single-stepping through it), the ctor has to be there. I'm guessing that you just used the .h file.

James Curran
  • 101,701
  • 37
  • 181
  • 258