Compiler asks for interface virtual constructor? - c++

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

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

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.

Related

virtual function in template inherited class

I am new to templates and I have searched the web for this error but I don't know how to fix it it.
Already checked Why can templates only be implemented in the header file?
State.h
template <class entityType>
class State
{
public:
State() = default;
virtual void Enter(entityType * owner);
};
EnterMine.h
#include "State.h"
class Miner;
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
virtual void Enter(Miner *) {
};
};
and Miner.cpp is blank
and the problem appears in main.cpp
#include "EnterMine.h"
int main()
{
EnterMine a;
}
The error I get is a linking error :
LNK2001 unresolved external symbol "public: virtual void __thiscall State::Enter(class Miner *)" (?Enter#?$State#VMiner####UAEXPAVMiner###Z)
(Note: this answer was written for the original question, it has been completely rewritten after that.)
Every function that is declared and used, should be defined somewhere.
It seems that you declare EnterMine::EnterMine() but never define it. If this constructor does nothing, either omit it (it will be implicitly defined by a compiler), or mark it as = default;.
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
...
};
This also applies to the State::State() constructor.
Even though it's a singleton, you're still calling the constructor. Thus, you will still need to define the constructor.
In fact, you need to define every function you declare in your header.

Unresolved external symbol in singleton

I've got code like this:
#pragma once
#include "MV/stateSystem/StateSystem.hpp"
#include "MV/config/Config.hpp"
namespace mv
{
class Initializator
{
/* ===Objects=== */
public:
protected:
private:
static Initializator *instance;
/* ===Methods=== */
public:
//Inits the program
void init();
static Initializator& getInstance();
static void createInstance();
protected:
private:
Initializator();
Initializator(Initializator const& copy) = delete; // Not Implemented
Initializator& operator=(Initializator const& copy) = delete; // Not Implemented
};
}
and .cpp
#include "Initializator.hpp"
namespace mv
{
Initializator* Initializator::instance;
void Initializator::init()
{
StateSystem::readStatesFromFile("data/states/states.txt");
}
Initializator & Initializator::getInstance()
{
if (instance == 0)
Logger::Log(constants::error::singleton::SINGLETON_NOT_INITED, Logger::STREAM::BOTH, Logger::TYPE::ERROR);
return *instance;
}
void Initializator::createInstance()
{
if (instance == 0)
instance = new Initializator();
}
}
but my compiler has got problem:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "private: __thiscall mv::Initializator::Initializator(void)" (??0Initializator#mv##AAE#XZ) referenced in function "public: static void __cdecl mv::Initializator::createInstance(void)" (?createInstance#Initializator#mv##SAXXZ)
I can't understand it because i've got other class where code is really similar and compiler hasn't got problem with it. In the past, when i've got this problem, i had to declare static members in .cpp file (for example: Initializator* Initializator::instance; ) but now it doesn't help me.
You are declaring the ctor, but not defining it
You can define it within class declaration with
Initializator() = default;
Or
Initializator(){};
Or also in the cpp with
Initializator::Initializator(){}
As the error message is saying, Initializator::createInstance() is calling the ctor, which has to be defined even if it is private
Declaring your default ctor as private prohibits the creation of an implicilty defined default ctor. Thus, you get the unresolved external symbol linker error.
To get it working, provide a valid ctor definition in your code.
Either in the .cpp file, or in the .hpp file ( by provding an in-class definition or writing ctor() = default forcing the automatic generation of a default constructor by the compiler ).

C++ Inheritance With No Default Constructors

So I was trying to implement a chess game. I've got the most common link error:
error LNK2019: unresolved external symbol "public: __thiscall Bishop::~Bishop(void)" (??1Bishop##QAE#XZ) referenced in function _main
So here are the two related classes:
Bishop.h (There is no "Bishop.cpp")
#pragma once
#ifndef BISHOP_H
#define BISHOP_H
#include "ChessPiece.h"
class Bishop : public ChessPiece
{
public:
Bishop(bool isWhite) : ChessPiece(isWhite) {
}
~Bishop(void);
// pure virtual functions
virtual CellLocation *listAvailableMoves(void) {
return 0;
}
virtual char getPieceType() {
return PIECE_TYPE_BISHOP;
}
};
#endif
ChessPiece.h (there is no "ChessPiece.cpp")
#ifndef CHESSPIECE_H
#define CHESSPIECE_H
#include "Globals.h"
// Abstract class for inheritence
class ChessPiece {
public:
// Constructor
ChessPiece(bool isWhite) : m_isWhite(isWhite) {
}
~ChessPiece(void);
// pure virtual functions
virtual CellLocation *listAvailableMoves(void) = 0;
virtual char getPieceType() = 0;
// ACCESSORS, MUTATORS
// isWhite member
bool isWhite(void) const{
return m_isWhite;
}
void setIsWhite(bool isWhite) {
m_isWhite = isWhite;
}
protected:
bool m_isWhite;
};
#endif
In the "Globals.h" there are few definitions of these but it's unrelated to my function.
So I what I've done in main was simply:
Bishop somePiece(true);
cout << sizeof(somePiece) << endl;
But it gave out the LNK2019 error.
Now I know that the solution should be to adding default constructors to both classes (which didn't work for some reason) but I don't want them to be initialized with default values. Hence I don't want default constructors for any of these classes.
Is there any way that I do not create default constructors and get away with it?
You are missing the definitions of ~ChessPiece(void); and ~Bishop(void);. That's what the compiler is complaining about.
Also notice that when you declare ChessPiece(bool), the default ChessPiece() constructor is not available anymore: hence you won't be able to default construct a ChessPiece.
But if you are on C++11 and for some reasons you want to delete the default constructor manually, you can use:
ChessPiece() = delete;
Your problem is about the destructor:
unresolved external symbol "public: __thiscall Bishop::~Bishop(void)"
^
// Notice the ~
You declared a destructor but didn't provide an implementation for it.

CLI/C++ link error 2028 and 2019

I've got a problem with passing templates (I think that's the cause) from the CLI project.
I've got 3 layers of classes (for encapsulation reasons and technical reasons).
I'll show an example of the buggy part (please no comments about the encapsulation reasons, they're not demonstrated here)
Class A is in a C++ DLL :
class A {
public:
template<class T>
void foo(T blah) { //Do stuff }
}
Class B wraps class A (also regular non-ref class):
class B {
public:
template<class T>
void foo(T blah) { a->foo(blah); }
private:
A* a;
}
Class C is a ref class, which calls class B with an explicit type :
ref class C {
public:
void foo(int blah) { b->foo(blah); }
private:
B* b;
}
They compile alright (.obj is created), but the linker doesn't link the objects correctly.
I get 2 linker errors for the method:
error LNK2028: unresolved token
(0A000645) "public: void __cdecl
B::foo(class utils::CustomString const
&,int const &)"
(??$foo#_N#B#Namespace##$$FQEAAXAEBVCustomString#utils##AEB_N#Z)
referenced in function "private: void
__clrcall C::foo(int)" (??$foo#_N#Namespace##$$FAE$AAMXPE$AAVString#System##_N#Z)
error LNK2019: unresolved external
symbol error LNK2019: unresolved
external symbol "public: void __cdecl
B::foo(class int const &)"
??$foo#_N#B#Namespace##$$FQEAAXAEBVCustomString#utils##AEB_N#Z)
referenced in function "private: void
__clrcall C::foo(int)" (??$foo#_N#Namespace##$$FAE$AAMXPE$AAVString#System##_N#Z)
Edit
I don't have the lines with me now (not on same PC) but it says it couldn't link B.foo referenced in C.foo
I'm compiling the ref class with /clr in debug mode /MDd (yes it has to be in debug mode because of other dependencies that are all compiled the same way)
Anyone knows why this is happening ? And more important: how to solve this ?
Edit:
When setting class B (the wrapper) to be compiled with /GL (Whole Program Optimization) I get a different error:
LNK2001:
error LNK2001: unresolved
external symbol "public: bool __cdecl
Interface::B::foo(int &)const "
(??$foo#_J#B#Namespace##$$FQEBA_NAEBVCustomString#123#AEA_J#Z)
The problem is a bug with visual studio's linker.
First of all, you need to set the /GL (Whole Program Optimization) flag so it links the template after compile.
Then you need to use one of these work-arounds:
BUG: LNK2001 on Member Function When Use Nested Class Template
This is standard lossage with C++ templates, they don't have external linkage like .NET generics. You have to put the template function definition in a header file so you can #include it in the source code file that contains the ref class. Just like your code snippet does. It isn't otherwise specific to C++/CLI.
Be sure to wrap the #include with #pragma managed if you compile the rest of the native classes without the /clr option (like you should). Like this:
#pragma managed(push, off)
#include "FileWithTemplateDefinition.h"
#pragma managed(pop)
These linker errors are pointing out that you are missing a definition somewhere (as opposed to a declaration). Not having access to your code makes this difficult for us to determine, especially without having any verbose linker errors.
[EDIT]
This code compiles and links for me just fine in a managed C++ project:
#pragma managed
class A {
public:
template<class T>
void foo(T blah) { int i = 0; }
};
//Class B wraps class A (also regular non-ref class):
class B {
public:
template<class T>
void foo(T blah) { a.foo(blah); }
private:
A a;
};
// Class C is a ref class, which calls class B with an explicit type :
ref class C {
public:
C() { b = new B(); }
~C() { }
!C() { delete b; }
void foo(int blah) { b->foo(blah); }
private:
B* b;
};

Accessing protected method from derived class in a different project (C++) generates linker error

I'm developing in native C++, using visual studio.
I have one project which contains infrastructures - base classes which I want to derive classes from in other projects in the same solution. Say I have a base class in the infrastructres project:
file base.h:
class Base
{
public:
void Foo();
protected:
void Bar();
};
and in another project, a class derived from A, try to call the method bar:
file derived.h:
class Derived : Base
{
public:
void DoSomething();
};
file derived.cpp:
void Derived::DoSomething()
{
Bar();
}
file main.cpp:
void main()
{
Derive d;
d.Foo(); //OK
d.DoSomething(); // Linker error
}
generates the following linker error:
Error 1 error LNK2001: unresolved external symbol "public: virtual void __thiscall Base::Bar(void)" (?Bar#Base##UAEXXZ) main.obj CplusplusTestProject
What am I doing wrong?
Make sure your Base::Bar() method has its implementation somewhere. You can just add curly bracers after its definition and rebuild your project.
The simplest possible problem is that you are not linking the library generated in the other project into your own executable.
You need a definition of the Bar member. Add a definition of Bar in the class definition or in a separate base.cpp file.