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.
Related
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 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.
I need to create some variable defined in class source private to that class only. I am not able to move this variable to class header because of some other header file issue. I found this page http://en.wikipedia.org/wiki/Opaque_pointer and explains how it can achieve,
Here is my class source
struct testClass::testStruct {
int a;
int b;
boost::asio::io_service io_service_2;
client c_3(io_service_2); // this is another class, getting error here
};
testClass::testClass(): test(new testStruct())
{
// do something
}
class header
class testClass
{
public:
testClass();
~testClass();
private:
struct testStruct;
testStruct* test;
};
While compile the I am getting the error
error: C2061: syntax error : identifier 'io_service_2'
Actually client is another class which I previously initialized as global
client c_3(io_service_2);
Now I cannot use it as global, I need to make it as private to the class, so choose above method.
Note: I cannot define client c_3 as class variable in class header because of some header issue. How can I resolve this issue?.
Thanks
Haris
I am working with templates in C++. Is there any difference in using templates and friend class when compiled with MSVC compiler and when using Mingw gcc compiler. My code successfully compiles and gives the desired output when compiled with MSVC but it gives error when compiled with gcc. Below is my code,
///////////Record.h/////////////////////
#include "Base.h"
class Derived1;
class Derived2;
template <class TYPE_LIST> class List;
class FRecord
{
public:
FRecord();
virtual ~FRecord();
friend class Base;
#if _MSC_VER <= 1200
friend class List<Derived1>;
friend class List<Derived2>;
#else
template <class TYPE_LIST> friend class List;
#endif
};
///////////////////////////////////////////////////////////////
///////////////////Base.h/////////////////////////////////
class Base
{
public:
Base(const HEADER *hc, const FRecord *fr);
virtual ~Base();
__inline bool IsNonValid() const;
protected:
quint32 Size;
};
/////////////////////////////////////
// Data
/////////////////////////////////////
template <class TYPE_LIST>
class Data : public TYPE_LIST
{
public:
Data(const HEADER *hc, const FRecord *fr) : TYPE_LIST(hc, fr)
{
QString val = IsNonValid() ? "Non" : "";
LOG0("Data ("<< val << " Valid)");
}
virtual ~Data()
{
LOG0("Data deleted");
}
}; // Data
///////////////////////////////////////////////////////////////////////////////////////
When compiled the above code with MSVC gives desired output but when compiled with Mingw GCC compiler it gives following error,
Base.h:1154: error: there are no arguments to 'IsNonValid' that depend on a template parameter, so a declaration of 'IsNonValid' must be available
Base.h:1553: error: 'Size' was not declared in this scope
What could be the possible solution to this problem?
Thanks in advance.
MSVC does not implement two-phase name lookup correctly. GCC is correct in reporting this error.
The cause is that names used inside a template which do not depend on the template's parameters are (should be in the case of VC) looked up when the template is defined, not when it's instantiated.
In your case, the compiler has no way of telling that IsNonValid will come from the base class, so it rightfully complains it doesn't know it. There are two possible solutions:
Qualify the access to IsNonValid, so that it's clear to the compiler it (potentially) depends on the template parameters:
QString val = this->IsNonValid() ? "Non" : "";
// or
QString val = TYPE_LIST::IsNonValid() ? "Non" : "";
Introduce the inherited name into the scope of the derived class:
template <class TYPE_LIST>
class Data : public TYPE_LIST
{
public:
using TYPE_LIST::IsNonValid;
// the rest as you had it originally
Either of these will make the name dependent and thus postpone its lookup until instnatiation, when the value of TYPE_LIST is actually known.
gcc is correct. You need to add this-> to delay lookup until instantiation time.
this->IsNonValid();
MSVC is non-conforming in that it delays all lookups until instantiation time as it doesn't properly implement two-phase name lookup.
Could anyone, please, explain what can cause this error?
Error: Invalid base class
I've got two classes where one of them is derived from second:
#if !defined(_CGROUND_H)
#define _CGROUND_H
#include "stdafx.h"
#include "CGameObject.h"
class CGround : public CGameObject // CGameObject is said to be "invalid base class"
{
private:
bool m_bBlocked;
bool m_bFluid;
bool m_bWalkable;
public:
bool draw();
CGround();
CGround(int id, std::string name, std::string description, std::string graphics[], bool bBlocked, bool bFluid, bool bWalkable);
~CGround(void);
};
#endif //_CGROUND_H
And CGameObject looks like this:
#if !defined(_CGAMEOBJECT_H)
#define _CGAMEOBJECT_H
#include "stdafx.h"
class CGameObject
{
protected:
int m_id;
std::string m_name;
std::string m_description;
std::string m_graphics[];
public:
virtual bool draw();
CGameObject() {}
CGameObject(int id, std::string name, std::string description, std::string graphics) {}
virtual ~CGameObject(void);
};
#endif //_CGAMEOBJECT_H
I tried cleaning my project but in vain.
It is not valid to define an array (std::string m_graphics[]) without specifying its size as member of a class. C++ needs to know the size of a class instance in advance, and this is why you cannot inherit from it as C++ won't know at runtime where in the memory the members of the inheriting class will be available.
You can either fix the size of the array in the class definition or use a pointer and allocate it on the heap or use a vector<string> instead of the array.