I would like to create a basic abstract class in C++, where the subclasses are each in a separate file. My abstract class looks something like
class Process_Base{
public:
virtual void process() = 0;
}
Should a simple implementation like this be contained entirely in a header file? If it is do I need to have a .cpp file associated with it?
When I create the subclasses what should their header file look? I was thinking .cpp file for the subclass should look something like
#include "Process_Base.h"
class Hello_Process : public Process_Base{
void process(){
printf("%s\n", "Hello, World");
}
}
Could someone verify that I am approaching this correctly, and if not give a simple example of what I should be doing.
UPDATE
I continued with the implementation but I am now getting the following compiler error
g++ -c -Wall -g Process_Message.cpp
Process_Message.cpp:4: error: expected class-name before ‘{’ token
The following is the abstract class header
// Abstract header .hpp file
class Process_Base{
public:
virtual void process() = 0;
};
the subclass header
// The subclass header .hpp file
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
and the implementation
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
I don't understand why I am getting the error, can someone please explain.
You're missing ; at the end of Process_Base declaration, when you include the file, the compiler goes nut. correct is:
class Process_Base{
public:
virtual void process() = 0;
};
Why this 'Process_Base' is there in below code? You have already mentioned inheritance in header file,right?
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
Also don't forget to type ';' at the end of the class declaration after '}'
Your correct code should look like this:
//Process_Message.h
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
//Process_Message.cpp
#include <stdio.h>
#include <string.h>
#include "Process_Message.h"
void Process_Message::process()
{
printf("%s", "Hello");
}
Don't forget to declare your overrides as virtual, or they will hide parent methods instead of implementing them.
#include <iostream>
class Process_Base
{
public:
virtual ~Process_Base() {}
virtual void process() =0;
};
class Process_Message : public Process_Base
{
public:
virtual void process(); // <- virtual
};
void Process_Message::process()
{
std::cout << "Hello";
}
The above should compile fine
Related
I got two classes separated in four files. The main class includes a sub class and needs to execute functions of it (not shown in the minimal example code). What I want to do is to execute a function of the main class in the scope of the subclass.
I think some ideas would be to inherit the functions in the sub class but I could not figure out how to do this.
MainClass.cpp
#include "MainClass.hpp"
void MainClass::mainCallback() {
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback() {
std::cout << "[subCallback] executed" << std::endl;
}
int main() {
MainClass mainClass;
mainClass.mainCallback();
SubClass subClass;
subClass.activateSubClass();
return 0;
}
MainClass.hpp
#pragma once
#include "SubClass.hpp"
#include <iostream>
class MainClass{
public:
void mainCallback();
void subCallback();
};
SubClass.cpp
#include "SubClass.hpp"
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
SubClass.hpp
#pragma once
class SubClass{
public:
void activateSubClass();
};
The error in SubClass.cpp is of course:
error: use of undeclared identifier 'mainClass'
Just subclass the subclass:
class SubClass: public MainClass {
public:
void activateSubClass();
};
This (public) way the SubClass makes all methods of MainClass callable in SubClass instances. You could also private inherit. That way only activateSubClass() 'ld be callable.
In activateSubClass you can call directly the methods of the parent class:
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
Don't forget to include MainClass.hpp in SubClass.hpp
You try to call a MainClass.subCallback() without having an instance of MainClass. According to me, this is the typical use case for static methods.
Then, I think you make your #include directives the wrong way. Indeed, MainClass does not seem to need to know SubClass but the opposite is true. I think it is better to include MainClass.hpp in SubClass.hpp. This will solve your circle dependencies problem.And you can write your main() function in another file.
EDIT: Example
MainClass.hpp:
#pragma once
class MainClass
{
public:
void mainCallback();
static void subCallback(); // mak it static to be able to call it without an instance of the class
};
MainClass.cpp:
#include "MainClass.hpp"
#include <iostream>
void MainClass::mainCallback()
{
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback()
{
std::cout << "[subCallback] executed" << std::endl;
}
SubClass.hpp:
#pragma once
class SubClass
{
public:
void activateSubClass();
};
SubClass.cpp:
#include "SubClass.hpp"
#include "MainClass.hpp" // MainClass inclusion
void Suclass::activateSubClass()
{
MainClass::subCallback(); // Call of the static method
}
main.cpp:
#include "MainClass.hpp"
#include "SubClass.hpp"
int main()
{
MainClass mc;
mc.mainCallback();
SubClass sc;
sc.activateSubClass(); // Will call MainClass::subCallback()
return 0;
}
I hope it can help you.
I'm noob in C++, and I have the following header file (Header.h)
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
using namespace std;
class Predicate
{
public:
virtual void print() = 0;
};
class UnaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
class BiaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
#endif
and in another separate .cpp file (Source.cpp), I tried to implement the print method, but got an "expected an expression" error.
#include "stdafx.h"
#include "Header.h"
#include <iostream>
using namespace std;
UnaryIntegerPredicate::UnaryIntegerPredicate() : Predicate()
{
virtual void print()
{
cout << "int : boolean" << endl;
}
}
what is wrong here, thanks!
I see you are probably coming from a Java background. What you need is
void UnaryIntegerPredicate::print()
{
cout << "int : boolean" << endl;
}
You don't need the stuff surrounding that. Since you have already declared in your header that UnaryIntegerPredicate derives from Predicate, you don't mention that again in the implementation file. You show that the print method that you are writing is the print method of the UnaryIntegerPredicate class by prefixing the name of the method with the name of the class as I have shown above.
You also don't need the virtual keyword in the cpp file because that is already specified in the header file.
I've got some problems here. I' am trying to make my code working like interface in java. This class is being inherited by 2 other by they are causing some problems.
And also i'd like to know if i am doing it correctly, the ways to improve my code. I'am novice.
Look:
Interface class:
#include <iostream>
#include <string>
class IZarzadzaniePozycjami{
public:
IZarzadzaniePozycjami(void);
~IZarzadzaniePozycjami(void);
public:
virtual void ZnajdzPozycjePoTytule();
virtual void ZnajdzPozycjePoId();
virtual void WypiszWszystkiePozycje();
};
#include "Pozycja.h"
#include "IZarzadzaniePozycjami.h"
#include <iostream>
#include <list>
Catalog class which inherites from IZarzadzanie... Class.
#include "Pozycja.h"
#include "IZarzadzaniePozycjami.h"
#include <iostream>
#include <list>
class Katalog : public IZarzadzaniePozycjami
{
private:
std::string dzialTematyczny;
public:
void ZnajdzPozycjePoTytule(std::string tytul);
void ZnajdzPozycjePoId(int id);
void WypiszWszystkiePozycje();
Katalog(void);
Katalog(std::string dzialTematyczny_);
void DodajPozycje(Pozycja);
std::list<Pozycja> lista;
friend bool operator==(const Katalog & kat, const std::string & s);
~Katalog(void);
};
inline bool operator==(std::string& s, Katalog& katalog)
{
return katalog == s;
}
and then library class(biblioteka.h) which alseo inherite from interface
#include<iostream>
#include "IZarzadzaniePozycjami.h"
#include "Bibliotekarz.h"
#include "Pozycja.h"
#include "Katalog.h"
class Biblioteka :
public IZarzadzaniePozycjami
{
public:
Biblioteka(void);
~Biblioteka(void);
Biblioteka(std::string adres_);
void DodajBibliotekarza(Bibliotekarz);
void WypiszBibliotekarzy();
void DodajKatalog(Katalog);
void DodajPozycje(Pozycja p, std::string dzialTematyczny);
void ZnajdzPozycjePoTytule(std::string tytul);
void ZnajdzPozycjePoId(int id);
void WypiszWszystkiePozycje();
private: std::string adres;
};
And here are some errors. Sorry for long post. Didn't know what to cut off.
c:\users\komputer\documents\visual studio 2012\projects\project1\izarzadzaniepozycjami.h(3): error C2011: 'IZarzadzaniePozycjami' : 'class' type redefinition
1> c:\users\komputer\documents\visual studio 2012\projects\project1\izarzadzaniepozycjami.h(3) : see declaration of 'IZarzadzaniePozycjami'
1>c:\users\komputer\documents\visual studio 2012\projects\project1\katalog.h(7): error C2504: 'IZarzadzaniePozycjami' : base class undefined
1>c:\users\komputer\documents\visual studio 2012\projects\project1\biblioteka.h(9): error C2504: 'IZarzadzaniePozycjami' : base class undefined
1> Generating Code...
1>c:\users\komputer\documents\visual studio 2012\projects\project1\katalog.cpp(16): warning C4717: 'operator==' : recursive on all control paths, function will cause runtime stack overflow
Use #pragma once in all the header files:
#pragma once
#include <iostream>
#include <string>
class IZarzadzaniePozycjami{
public:
IZarzadzaniePozycjami(void);
~IZarzadzaniePozycjami(void);
....
and make sure the header with IZarzadzaniePozycjami is included everywhere before IZarzadzaniePozycjami is used.
You declare
virtual void ZnajdzPozycjePoTytule();
but in your classes you declare (and I hope you define)
void ZnajdzPozycjePoTytule(std::string tytul);
These are not the same methods. A method signature includes its parameters, so your virtual method is still unimplemented.
What you're calling an "Interface" class is not the same as the Java concept. In java an interface has no implementation, but the class you've defined, must have an implementation defined. You can avoid defining the virtual methods if you make them pure virtual (e.g. = 0), but you must provide an implementation for the all non-pure virtual methods of IZarzadzaniePozycjami. In its current form, that means every method must be defined. This is why it won't compile.
I know it is one of the constant ask question
so i get this error
'WorldObject': [Base class undefined (translated from german)]
Here is the code which produce this error:
ProjectilObject.h:
#pragma once
#ifndef _PROJECTILOBJECT_H_
#define _PROJECTILOBJECT_H_
#include "GameObjects.h"
class ProjectilObject: public WorldObject
{
public:
ProjectilObject(IGameObject* parent,int projectiltype);
void deleteyourself();
protected:
virtual void VProcEvent( long hashvalue, std::stringstream &stream);
virtual void VInit();
virtual void VInitfromStream( std::stringstream &stream );
virtual void VonUpdate();
virtual void VonRender();
private:
vec3 vel;
float lifetime;
float lifetimeend;
vec3 target;
int m_projectiltype;
};
#endif
Here is the code file from the WorldObject class:
GameObjects.h:
#pragma once
#ifndef _GAMEONJECTCODE_H_
#define _GAMEONJECTCODE_H_
#include "IGameObject.h"
#include "Sprite.h"
#include "GamePath.h"
#include "HashedString/String.h"
#include "IAttribute.h"
#include "CharacterObjects.h"
#include "ProjectilObject.h"
[...]
class WorldObject: public IGameObject, public MRenderAble
{
public:
WorldObject(IGameObject* parent);
virtual bool IsDestroyAble();
virtual bool IsMageAble();
virtual bool IsRenderAble();
protected:
virtual void VProcEvent( long hashvalue, std::stringstream &stream);
virtual void VonUpdate();
virtual void VonRender();
virtual void VInit() =0;
virtual void VInitfromStream( std::stringstream &stream ) =0;
virtual void VSerialize( std::stringstream &stream );
vec3 poscam;
};
[...]
#endif
There are some other Classes in this file but they shouldn't interrupt, I think.
Maybe there is a tiny error I didn't saw but I don't understand why this error is produced. When you need more of the code feel free to ask because i think it would only disturb.
If you have any source file that includes GameObjects.h before ProjectilObject.h or does not include ProjectilObject.h directly, then the compiler will first find the declaration of ProjectilObject through the include in GameObjects.h before knowing what WorldObject is. That is because GameObjects.h first includes ProjectilObject.h and then declares WorldObject. In that case the include of GameObjects.h present in ProjectilObject.h won't work because _GAMEONJECTCODE_H_ will be already defined.
To avoid this, either be sure to include ProjectilObject.h instead of GameObjects.h in your source file, or use forward declarations.
It's hard to answer this question without looking at the whole code. Even a misplaced brace could count. Check your namespaces - are you sure the WorldObject is in the same namespace?
I suggest you use the #pragma message by placing it near the WorldObject definition and checking the compiler output:
#pragma message ("World object is defined")
If it does not show up, move the pragma to the parent .h file and check the compiler output again. With this you can easily locate the error.
class WorldObject;
class ProjectilObject: public WorldObject
You are forward declaring WorldObject, but to inherit from a class you need the definition, so you have to include the header of WorldObject.
In my case: i delete derived class include from base class header file.
for example:
file 1 :
#include "B.h"
-> A()
file 2:
-> B() : A()
solution : delete #include "B.h" from file1
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.