OK, I have been looking about but can not for the wits of me find a reason to why this should not work:
Base class (misc/interface/handler.h)
#ifndef __t__MISC_VIRTUAL_HANDLER_H
#define __t__MISC_VIRTUAL_HANDLER_H
#pragma message("Starting with 'handler.h'")
namespace t {
namespace misc {
namespace interface {
class Handler {
public:
Handler();
virtual ~Handler();
virtual int setup() = 0;
virtual int teardown() = 0;
virtual int update() = 0;
protected:
private:
};
}
}
}
#pragma message("Ending with 'handler.h'")
#endif // __t__MISC_VIRTUAL_HANDLER_H
Derived class (graphics/handler.h):
#ifndef __t_GRAPHICS_HANDLER_H
#define __t_GRAPHICS_HANDLER_H
#include "../misc/interface/handler.h"
namespace t {
namespace graphics {
class Handler: public t::misc::interface::Handler {
public:
Handler();
virtual ~Handler();
int getResolutionX() { return m_resolutionX; }
int getResolutionY() { return m_resolutionY; }
bool getFullscreen() { return m_isFullscreen; }
protected:
private:
unsigned int m_resolutionX, m_resolutionY;
bool m_isFullscreen;
}; // class Handler
} // namespace graphics
} // namespace t
#endif // __t_GRAPHICS_HANDLER_H
... which seems rather trivial.
Derived class implementation (graphics/handler.cpp):
#include "handler.h"
t::graphics::Handler::Handler(): t::misc::interface::Handler() {
}
t::graphics::Handler::~Handler() {
}
... which too is should be really trivial, but yields the error:
src\graphics\handler.cpp|5|undefined reference to `t::misc::interface::Handler::Handler()'
I'm using MinGW with Code Blocks and what ever standard settings CB uses, I've tried building the same situation with test classes and that works as intended, both in same environment and Linux with vanilla g++.
I can't see any implementation of t::misc::interface::Handler::Handler() in your code - and it is going to be called by the inheriting class's constructor, so it needs an implementation. The linker can't find it, so it complains.
Just change:
Handler();
virtual ~Handler();
in the abstract class to:
Handler() {}
virtual ~Handler() {}
and you're ready to go.
As an aside, identifiers starting with two underscores are illegal in C++ (since they are reserved for the compiler). In practice, they shouldn’t be a problem in preprocessor but it’s best to err on the safe side here: simply don’t use them.
Related
To begin, I know that there are a lot of questions about this but I didn't find a solution for this, so I decided to write it.
I'm working on a C++ project and I need to use polymorphism. In order to solve my problem, I simplified it into two classes: Parent and Child. The Parent has only virtual methods, and the Child has to implement them. The only class that will be instantiated is the Child. So, here is the code:
Parent.hh
namespace ParentNamespace {
class Parent {
public:
Parent();
~Parent();
virtual int Start() = 0;
};
}
Parent.cc
#include "Parent.hh"
using namespace ParentNamespace;
namespace ParentNamespace {
Parent::Parent(){}
Parent::~Parent(){}
}
Child.hh
#include "Parent.hh"
namespace ChildNamespace {
class Child : public ParentNamespace::Parent {
public:
Child();
~Child();
int Start();
};
}
Child.cc
#include "Child.hh"
namespace ChildNamespace {
Child::Child(){}
Child::~Child(){}
int Start(){
return 0;
}
}
It compiles without errors (it produces .o files), but when it has to link them, it shows this error:
In function ChildNamespace::Child::Child():
Child.cc:8: undefined reference to vtable for ChildNamespace::Child
I've tried with the responses from the other questions, but no success. I suppose that I can't see something simple, so please help!
Thanks in advance.
You need to implement the pure virtual function, add Child::
to Start method
In Child.cc
#include "Child.hh"
namespace ChildNamespace {
Child::Child(){}
Child::~Child(){}
int Child::Start(){
return 0;
}
}
I hope this help you
I have such class
#ifndef _OBJECT_H_
#define _OBJECT_H_
#include <iostream>
#include <functional>
namespace core {
class Object {
protected:
template <>
struct std::hash<core::Object>
{
size_t operator()(const core::Object &x) const = 0;
};
public:
virtual Object* clone() = 0;
virtual int hashCode() = 0;
virtual std::string getClass() = 0;
virtual ~Object();
};
}
#endif
I want to force all inherited classes to implemented hash calculation and provide ability to get hashcode using implemented method for overriding () in hash struct.
However my compiler shows Symbol 'hash' could not be resolved error.
I am using Eclipse c++ with CDT plugin and TDM gcc 5.1.0. What's the problem?
If you want to add an explicit specialization to std::hash for Object, the correct way to do it is this:
namespace core {
class Object { ... };
}
namespace std {
template <>
struct hash<core::Object> {
size_t operator()(const core::Object& x) const {
return x.hashCode(); // though to make this work,
// hashCode() should be const
}
};
}
The explicit specialization must be in namespace scope - in std's scope, specifically. And you can only make virtual functions pure (= 0), this one shouldn't be virtual or pure.
Side-note, your _OBJECT_H include guard is a reserved identifier. You should choose another one.
Alright, I just thought give C++ a try (I currently do C#), now my first problem is class instantiating or calling a method in another class.
Here is my code:
My main Program entry:
#include <iostream>
#include "myClass.h"
using namespace std;
int main()
{
myClass* mc = new myClass();
}
The Class I'm trying to access:
#include "myClass.h"
myClass::myClass()
{
void DoSomething();
{
}
}
myClass::~myClass()
{
}
The Class Header:
#pragma once
class myClass
{
public:
myClass();
~myClass();
};
Now as you can see i have instantiated the class, but i cant access DoSomething() method.
This code simply declares a local function, and has an empty scope for fun:
myClass::myClass()
{
void DoSomething(); // local function declaration
{
// empty scope
}
}
If you want doSomething() to be a member of myclass, you have to declare it in the class definition:
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
then implement it
void myclass::doSomething() { .... }
Also note that you don't have to use new everywhere in C++. You can instantiate an object like this:
int main()
{
myClass mc;
}
Also note that using namespace std; isn't such a great idea anyway, at least not in real code.
this is a function declaration in a constructor (+an ampty scope within { }).
myClass::myClass()
{
void DoSomething();
{
}
}
You want a function declaration in class body (not in constructor) and definition of this function (this can be done immediately together with declaration or later as i.e. here):
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
implementation of constructor:
myClass::myClass() { .... }
implementation of your function, similarly:
void myClass::doSomething() { .... }
The method you are trying to use in main must be part of the class definition. You can write an inline function or can have a separate definition of that function. Also, you need to make that function public in order to access it from main.
I asked a while ago how to use virtual classes in c++, and to my dismay i learned that you can't. But one user,(namely "Emilio Garavaglia" thanks a bunch), posted a way to get something similar to virtual classes, just with some extra code. however, i'm having some trouble getting what i'm doing to compile. here's the code:
global_defs.h
#define Interface class
#define abstract_class class
#define implements : public
I_Graphics.h
#ifndef I_GRAPHICS_H
#define I_GRAPHICS_H
#include <string>
#include "global_defs.h"
Interface I_Graphics
{
public:
virtual ~I_Graphics() {};
virtual void Initialize() = 0;
virtual void Frame() = 0;
virtual void Shutdown() = 0;
class I_Model;
virtual I_Model * CreateModel() = 0;
};
Interface I_Graphics::I_Model
{
public:
virtual ~I_Model() {}
virtual void Initialize(std::string const & filename, std::string const & textureFilename) = 0;
virtual void * GetVertexBuffer() = 0;
virtual void * GetIndexBuffer() = 0;
};
#endif
Graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "global_defs.h"
#include <map>
#include <string>
#include <memory>
#include "I_Graphics.h"
class Graphics implements I_Graphics
{
public:
Graphics();
~Graphics();
void Initialize();
void Frame();
void Shutdown();
class Model;
I_Model * CreateModel() {return new Model;} // <--- compile error here
private:
std::map <std::string, I_Model *> m_ModelList;
};
class Graphics::Model implements I_Graphics::I_Model
{
public:
Model();
~Model();
void Initialize(std::string filename, std::string textureFilename);
void * GetVertexBuffer();
void * GetIndexBuffer();
};
#endif
Graphics.cpp
nothing going here, havn't really started working on the hard part yet, just trying to get the model instantiation to work.
#include "Graphics.h"
Graphics::Graphics()
{
}
Graphics::~Graphics()
{
}
void Graphics::Initialize()
{
}
void Graphics::Frame()
{
}
void Graphics::Shutdown()
{
}
Graphics::Model::Model()
{
}
Graphics::Model::~Model()
{
}
void Graphics::Model::Initialize(std::string filename, std::string textureFilename)
{
}
void * Graphics::Model::GetVertexBuffer()
{
return NULL;
}
void * Graphics::Model::GetIndexBuffer()
{
return NULL;
}
so, as the little comment says, i get an error there saying:
error C2512: 'Graphics::Model' : no appropriate default constructor available
when there obviously is a constructor for it in graphics.cpp . Can someone please explain what the compiler is complaining about here?
EDIT:
not sure if it means anything, but when mousing over the little red squiggle in MSVC, it says, "object of abstract class type Graphics::Model is not allowed" . ...but it doesn't have any pure virtual members, so it's not abstract right?
EDIT:
On the suggestion of Castilho, i declare CreateModel in graphics.h like before, but then defined it in graphics.cpp, and it yielded a much more specific error, but i still don't understand why.
error C2259: 'Graphics::Model' : cannot instantiate abstract class
1> due to following members:
1> 'void I_Graphics::I_Model::Initialize(const std::string &,const std::string &)' : is abstract
1> i_graphics.h(28) : see declaration of 'I_Graphics::I_Model::Initialize'
You're using the Model class before it is defined. Define the function CreateModel in a separate CPP and it may work.
When I have a header file like this:
#ifndef GAMEVIEW_H_
#define GAMEVIEW_H_
#include <SDL/SDL.h>
class GameView
{
public:
GameView();
virtual ~GameView();
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
#endif /* GAMEVIEW_H_ */
I need to create a .cpp file like this:
#include "GameView.h"
GameView::~GameView()
{
}
GameView::GameView()
{
}
This is a bit stupid. Just a .cpp file for an empty constructor and deconstructor.
I want to implement that method simply in the header file. That is much cleaner.
How to do this?
You can define your constructor and destructor (this is the proper term, use this instead of deconstructor) inline:
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
I want to implement that method simply in the header file. That is much cleaner.
So be it.
// ...
GameView() { }
virtual ~GameView() { }
// ...
You don't even need to write this. The compiler provides a default constructor itself. The only thing you need is the destructor because it's not virtual by default.
In case you heard you need to define these in the .cpp file - this is sometimes needed if you have smart pointers in your class as members. A rule of thumb is that when you have smart pointers to in your class, and they point to a class that's just forward declared in the header, always provide constructors and destructors in the .cpp file where you actually define the pointed-to class. Otherwise you can get problems with deletion of incomplete classes (causing undefined behavior in many cases).
#ifndef GAMEVIEW_H_
#define GAMEVIEW_H_
#include <SDL/SDL.h>
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
#endif /* GAMEVIEW_H_ */
I don't see your problem:
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
And of course if the constructor does nothing, there is no need to provide it all.