I am attempting to override an abstract class that has been declared inside a DLL in another project, however, when I try to init the overriding class, I receive compilation errors.
These are visual studio projects, as such,the built-in compiler of visual studio are used to compile all code.
I have a template class in a DLL:
#ifndef __IINPUT_RECEIVER_H_
#define __IINPUT_RECEIVER_H_
#ifdef HUMANINTERACTION_EXPORTS
#define HUMANINTERACTION_API __declspec(dllexport)
#else
#define HUMANINTERACTION_API __declspec(dllimport)
#endif
namespace HumanInteraction
{
template<typename T>
class HUMANINTERACTION_API IInputReceiver
{
public:
virtual ~IInputReceiver()
{}
/**
* Called when new input is received
*/
virtual void onInput(const T& refInput) = 0;
};
}
#endif
In another project which is to use this DLL, I inherit from this class and override its method, like so:
class Receiver : public IInputReceiver<wchar_t*>
{
public:
/**
* Called when new input is received
*/
virtual void onInput(const wchar_t*& refInput)
{
wstring str(refInput);
wcout << L"Received: " << str << endl;
}
};
But when I try to init an instance of class Receiver I receive the following compilation error; I am omitting unrelated logs:
1>c:\users\dominik\documents\visual studio 2013\projects\profile\profile\profile.cpp(25): error C2259: 'Receiver' : cannot instantiate abstract class
1> due to following members: 1> 'void
HumanInteraction::IInputReceiver::onInput(const T &)' : is abstract
The line profile.cpp(25) attempts to init an instance of Receiver, like so - nothing special here:
Receiver receiver;
Of course the compiler is right that onInput in the base class in a pure virtual function, however, I override this function in my derived class. Therefore, the class Receiver is not abstract as the log indicates.
Though usually I tend to fix my issues on my own, I have absolutely no clue whatsoever this time why this error is occuring - absolutely void.
I would greatly appreciate any contribution to this problem, even if it is 'only' comments.
The signature of the virtual member function in the base class is
virtual void onInput(const T& refInput) = 0;
The one in the derived class is
virtual void onInput(const wchar_t*& refInput)
What you need to use is:
virtual void onInput(wchar_t* const& refInput)
It will make more sense if you use
virtual void onInput(T const& refInput) = 0;
in the base class.
Related
I have recently run into this problem when using NVI with a template base class across compilation different units. If I have two classes deriving from my base class with the same template argument (but differing behavior), I get a multiple symbol definition error for HandleData(), the indirection method in the base class.
Additionally marking HandleData() as inline did not change the error. Inclusion guards are in place and correct.
I'm grateful for any and all ideas!
Update:
The main problem appears to be the template instantiation: If I put both unit tests into the same file, they run correctly - the problems appears only if derived classes are instantiated in different files (compilation units) of the same DLL (UnitTest.dll, I happen to use CPPUnit btw.)
Base class (in DLL X):
template <class DataType>
class cDataHandlerBase
{
public:
virtual ~cDataHandlerBase();
bool HandleData(const std::vector<DataType>& data)const
{
return doHandleData(data);
}
protected:
cDataHandlerBase();
private:
virtual bool doHandleData(const std::vector<DataType>& data)const = 0;
};
Derived classes (in DLL Y, files A and B):
class cDataHandlerA : public cDataHandlerBase<SomeType>
{
virtual bool doHandleData(const std::vector<DataType>& data)const override;
};
class cDataHandlerB : public cDataHandlerBase<SomeType> //same type as cDataHandlerA!
{
virtual bool doHandleData(const std::vector<DataType>& data)const override;
};
UnitTest-DLL contains files TestA and TestB, upon compiling these I get multiple definitions of cDataHandlerBase::HandleData().
I have been developing a C++ game engine for a long time. I have never had any issues with the compiler, or anything like that, until I update to Xcode 8.3.1!
Suddenly, it appears that a default setting was changed when I updated that made it so that the compiler simply cannot handle circular references.
Does anyone know how to set this back, (I tried downgrading Xcode, and it still doesn't work!)
My circular referencing looks something like this:
I have a class called "Object" defined in my code
"Object" includes another class called "Renderer2D"
"Renderer2D" includes another class called "Renderable2D"
"Renderable2D" extends "Object"
My "Object" class:
#pragma once
#include "Graphics/2D/Renderer2D.h"
namespace kineticengine {
class Object {
public:
Object();
virtual ~Object() {}
virtual void render(graphics::Renderer2D* renderer) const;
};
}
My "Renderer2D" class:
#pragma once
#include "Renderable2D.h"
namespace kineticengine {
namespace graphics {
class Renderer2D {
protected:
Renderer2D() {}
public:
virtual void submit(const Renderable2D* renderable) {}; // Error here, "Unknown type name 'Renderable2D', did you mean 'Renderer2D'?"
};
}
}
My "Renderable2D" class:
#pragma once
#include "Renderer2D.h"
#include "../../Object.h"
namespace kineticengine {
namespace graphics {
class Renderable2D : public Object {
public:
Renderable2D() : Object() {}
virtual ~Renderable2D() {}
void render(Renderer2D* renderer) const override {
renderer->submit(this); // Error here "Cannot initialize parameter of type 'const kineticengine::graphics::Renderer2D *' with an rvalue of type 'const kineticengine::graphics::Renderable2D *'"
}
};
}
}
All of my errors are basically variations of "Unknown class [x]" where x is one of the other classes.
Any help would be appreciated!
Renderable2D.h is including Renderer2D.h before defining class Renderable2D, so when Renderer2D.h refers to class Renderable2D, it is not yet defined. Clang is behaving correctly.
One way to break this cycle is to not include headers if you're only going to refer to a class by pointer or reference. You then put a forward declaration for the class in instead of the include directive. This has the added bonus of speeding up compile time as well.
I'm trying to make the following implementation work:
Header of base class:
#ifndef BASE_HH
#define BASE_HH
namespace base {
class Agent
{
public:
int loop () {return loopImpl();}
protected:
virtual int loopImpl() =0;
}
#endif
Header or derived class:
#ifndef DERIVED_HH
#define DERIVED_HH
#include <base/agent.hh>
namespace derived {
class Agent : public base::Agent
{
protected:
virtual int loopImpl();
}
#endif
Source file of derived class:
#include <derived/agent.hh>
int Agent::loopImpl()
{
return 0;
}
Now, when I compile this in the terminal and test it, it works. But when I try compiling an S-function in Matlab that creates an Agent object, i get the following error:
Error using mex
/path/sfunction.cpp In function ‘void mdlStart(SimStruct*)’:
/path/sfunction.cpp:51:56: error: invalid new-expression of abstract class type ‘derived::Agent’
derived::Agent *agent = new derived::Agent ();
/derived_path/agent.hh:28:11: note: because the following virtual functions are pure within ‘derived::Agent’:
class Agent: public base::Agent
In file included from /derived_path/agent.hh:22:0, from /path/sfunction.cpp:13:
/base_path/agent.hh:54:21: note: virtual int base::Agent::loopImpl() virtual int loopImpl () =0;
So it seems the g++4.9 compiler is unable to find the derived member function... Could anybody give me some hints on why this is so and what to do about it? As mentioned above, when I compile a similar file creating an object of the same derived class, it works.
Thank you for your time.
I've a question about an error I get by inherenting a template base class. I get this error in my subclass source file:
error: class ‘JobCalcReturn’ does not have any field named ‘JobMaster’
my base class as a *.h file:
template<class dataIn, class dataOut>
class JobMaster
{
public:
JobMaster() : JSONin("NOP"){};
JobMaster(const std::string &_JSONin) : JSONin(_JSONin){};
virtual ~JobMaster(){};
private:
static dataIn dataInObject;
static dataOut dataOutObject;
const std::string &JSONin;
static std::string JSONout;
virtual std::string dataInHandler(dataIn& dataInObject){...};
//Some more virutal methodes
};
my subclass header:
class DataInClass{...};
class JobCalcReturn :public JobMaster<DataInClass, Poco::JSON::Array>
{
public:
JobCalcReturn(const std::string &_JSONin);
~JobCalcReturn();
private:
std::string dataInHandler(DataInClass& calcRatrunData);
};
my subclass source file:
JobCalcReturn::JobCalcReturn(const std::string& _JSONin) : JobMaster(_JSONin){}
//here in the constructor i get the error
JobCalcReturn::~JobCalcReturn(){}
std::string JobCalcReturn::dataInHandler(DataInClass& calcRatrunData){...}
I wrote this with Visual Studio 2013 and got no error, then I switch the system to Linux with eclipse and the gcc c++ compieler and I get this error. Does someone has a clue why I get this error?
Jobmaster is a class template. So you need to provide the template arguments in the JobCalcReturn constructor's definition:
JobCalcReturn::JobCalcReturn(const std::string& _JSONin)
: JobMaster<DataInClass, Poco::JSON::Array>(_JSONin){}
Also note that _JSONin is a reserved identifier. You need to use a different name.
I find one of the most time-consuming compiler errors for me is "cannot instantiate abstract class," since the problem is always that I didn't intend for the class to be abstract and the compiler doesn't list which functions are abstract. There's got to be a more intelligent way to solve these than reading the headers 10 times until I finally notice a missing "const" somewhere. How do you solve these?
cannot instantiate abstract class
Based on this error, my guess is that you are using Visual Studio (since that's what Visual C++ says when you try to instantiate an abstract class).
Look at the Visual Studio Output window (View => Output); the output should include a statement after the error stating:
stubby.cpp(10) : error C2259: 'bar' : cannot instantiate abstract class
due to following members:
'void foo::x(void) const' : is abstract
stubby.cpp(2) : see declaration of 'foo::x'
(That is the error given for bdonlan's example code)
In Visual Studio, the "Error List" window only displays the first line of an error message.
C++ tells you exactly which functions are abstract, and where they are declared:
class foo {
virtual void x() const = 0;
};
class bar : public foo {
virtual void x() { }
};
void test() {
new bar;
}
test.cpp: In function ‘void test()’:
test.cpp:10: error: cannot allocate an object of abstract type ‘bar’
test.cpp:5: note: because the following virtual functions are pure within ‘bar’:
test.cpp:2: note: virtual void foo::x() const
So perhaps try compiling your code with C++, or specify your compiler so others can give useful suggestions for your specific compiler.
C++Builder tells you which method is abstract:
class foo {
virtual void x() const = 0;
};
class bar : public foo {
virtual void x() { }
};
new bar;
[BCC32 Error] File55.cpp(20): E2352 Cannot create instance of abstract class 'bar'
[BCC32 Error] File55.cpp(20): E2353 Class 'bar' is abstract because of 'foo::x() const = 0'