I've been having a bit of trouble lately in C++ with virtual methods/inheritance
At first if i try to extend a super class i get this error:
'Undefined reference to GameState::GameState()'
but if i remove the constructors all together i don't get the above error but i end up with a segmentation fault which occurs when calling the virtual method.
This is my code:
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <stdlib.h>
#include "Resources.h"
#include "Renderer.h"
class GameState {
public:
GameState();
virtual void init(Resources *res) = 0;
virtual void exit() = 0;
virtual void update() = 0;
virtual void render(Renderer *renderer) = 0;
};
#endif // GAMESTATE_H
and this is the subclass:
#include "GameState.h"
class MainGameState : public GameState {
public:
MainGameState() : GameState() {
}
virtual void init(Resources *res) {
}
virtual void update() {
printf("test\n");
}
virtual void render(Renderer *renderer) {
}
virtual void exit() {
}
private:
SDL_Surface *image;
};
Try
GameState() { }
instead of
GameState();
or define it somewhere else.
Though, I'm not sure if it has anything to do with virtual methods. I think there's a bug elsewhere. Perhaps, uninitialized pointer?
You need to provide an implementation for the constructor if you want to explicitly call it:
class GameState {
public:
GameState() {} // implementation
virtual void init(Resources *res) = 0;
virtual void exit() = 0;
virtual void update() = 0;
virtual void render(Renderer *renderer) = 0;
};
Here is a complete program which implements the base and derived classes you are looking for. You receive the linker error message because you never implemented GameState::GameState. It isn't clear why you got the segmentation fault.
Remember also, if you want to delete your objects polymorphically, declare and define a virtual base-class destructor.
#include <iostream>
#define X() (std::cout << __FUNCTION__ << "\n")
class GameState {
public:
GameState() { X(); }
virtual ~GameState() { X(); }
virtual void F() = 0;
};
class MainGameState : public GameState {
public:
MainGameState() : GameState() { X(); }
void F() { X(); }
~MainGameState() { X(); }
};
int main () {
GameState* pGS = new MainGameState;
X();
pGS->F();
delete pGS;
}
This error 'Undefined reference to GameState::GameState()' tells you that GameState constructor isn't defined. It has nothing to do with virtual method.
Do what #Luchian and #Micheal said:
class GameState {
public:
GameState() {} // implementation
If it was a virtual method error, you would get something like "the 'MainGameState' must implement inherited pure virtual method 'method name'"
EDIT: Note that the super class constructor is implicitly called when you instantiate a sub-class.
The compiler will call a parameterless base class constructor (default constructor) for you anyway, so it is unnecessary. However, are you even providing a definition for GameState::GameState()? Probably not, so you should just get rid of it or provide an implementation (i.e., GameState() { }).
We need to see how you are calling the function. That looks fine to me, your bug is somewhere else. Are you perhaps declaring a pointer to an object, not initializing it, and then calling update()?
If I have to guess (and apparently I do...) I would bet that you have something like this:
MainGameState *state;
state->update(); // oops! Not initialize!
Of course I may be wrong, but like I said, I am forced to guess until you update your question with the real code.
Related
I have a parent class that invokes a callback that is abstract. The child class is meant to override this callback, but must never call it on its own from its code.
class Parent(){
public:
void Init(){ MyCallback(); }
protected:
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ }
private:
void SomeCode{ MyCallback(); }//<---how to prevent this?
}
There are many callbacks such as these. I don't want the user to get lost and think that he should call any of them manually.
Is it possible to prevent these callbacks from being invoked by child class?
I don't think there is a way to enforce the rules you want at compile-time, but you can enforce them at runtime via assertion-failures, which is the next-best thing, since at least anyone who breaks the rule will learn the error of their ways the next time they run the program. Note that I've added a requirement that the subclass-overrides of MyCallback() must call up to the superclass-method exactly once, to prevent subclasses from gratuitously making additional calls to MyCallback() on themselves or their superclasses inside the callbacks-are-allowed context.
#include <stdio.h>
#include <stdlib.h>
class Parent
{
public:
Parent() : _okayToCallCount(0), _numParentClassCallsMade(0) {/* empty */}
protected:
virtual void MyCallback()
{
if (_okayToCallCount == 0) {printf("MyCallback() was called from an invalid context!\n"); abort();}
_numParentClassCallsMade++;
if (_numParentClassCallsMade > 1) {printf("Parent::MyCallback() was called more than once from the subclass's override-method!\n"); abort();}
}
private:
// This is the only place that MyCallback should EVER be called from!
void TheOnlyPlaceThatMyCallbackShouldEverBeCalledFrom()
{
_numParentClassCallsMade = 0;
_okayToCallCount++;
MyCallback();
_okayToCallCount--;
if (_numParentClassCallsMade < 1) {printf("Parent::MyCallback() was never called from the subclass's override-method!\n"); abort();}
}
int _okayToCallCount;
int _numParentClassCallsMade;
};
class Child : public Parent
{
public:
Child() {}
void SomeCode() { MyCallback(); }//<---how to prevent this?
protected:
virtual void MyCallback()
{
Parent::MyCallback(); // REQUIRED!
}
};
int main(int argc, char ** argv)
{
Child c;
c.SomeCode();
return 0;
}
Your Program had soo many mini Errors
class Parent(){ // These braces**()** don't come after a class's name
public:
void Init(){ MyCallback(); }
protected: // Because the datatype is protected, it can't be accessed properly (overrided) by **Main Function**
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ }
private:
void SomeCode{ MyCallback(); }//<---how to prevent this? // You forgot the braces here **()**
} // You forgot the semi-colon **;**
Here I have fixed them for you:-
#include <iostream>
using namespace std;
class Parent {
public:
void Init(){ MyCallback(); }
//protected:
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ cout <<"Child Class Function!"; }
private:
void SomeCode() { MyCallback(); }//<---how to prevent this?
};
int main()
{
Parent* ptr_base;
Child derived;
ptr_base = &derived;
ptr_base->MyCallback();
}
I am no doubt overlooking something basic but my implementation is obviously flawed.
I am trying to require a derived classes to implement a method being called in a base class.
class IClock
{
public:
virtual void OnTimeExpired() = 0;
}
class Clock : public IClock
{
... // ABC not implemented
}
class Application : public Clock
{
... // ABC not implemented
}
class DerivedApp : public Application
{
public:
virtual void OnTimeExpired() { ... }
}
I rarely use pure ABCs, so I thought by not defining the pure virtual method in Clock and Application, it would require all derivatives of Application to define the OnTimeExpired() method.
I discovered this will compile and link (MSVS-2017) and if DerivedApp does not implement the method, the Clock object will call an undefined method and crash.
Why does this compile without the pure virtual method being implemented?
How do I force derived Application classes to implement the OnTimeExpired() method?
EDIT: The crash was due to unrelated error - I apologize. Nevertheless the questions I ask are still applicable.
As requested here is a complete, buildable, minimal example:
IClock.h:
#pragma once
class IClock
{
public:
virtual void OnClockTime() = 0;
};
Clock.h:
#pragma once
#include "IClock.h"
class Clock : public IClock
{
public:
Clock();
virtual ~Clock();
void ClockUpdate();
virtual void OnClockTime();
private:
float elapsed_time;
};
Clock.cpp:
#include "Clock.h"
Clock::Clock()
: elapsed_time(0.0f)
{
}
Clock::~Clock()
{
}
void Clock::ClockUpdate()
{
elapsed_time += 0.0000001f; // small ticks for testing
if (elapsed_time >= 1.0f) {
OnClockTime();
elapsed_time -= 1.0f;
}
}
void Clock::OnClockTime()
{}
ApplicationBase.h
#pragma once
#include "Clock.h"
class ApplicationBase : public Clock
{
public:
ApplicationBase();
virtual ~ApplicationBase();
virtual void Init(){}
virtual void Run(){}
protected:
bool app_run;
};
ApplicationBase.cpp:
#include "ApplicationBase.h"
ApplicationBase::ApplicationBase()
: app_run(false)
{
}
ApplicationBase::~ApplicationBase()
{
}
DerivedApp.h:
#pragma once
#include "ApplicationBase.h"
class DerivedApp : public ApplicationBase
{
public:
DerivedApp();
virtual ~DerivedApp();
virtual void Init() {}
virtual void Run();
//virtual void OnClockTime();
};
DerivedApp.cpp:
#include "DerivedApp.h"
#include <iostream>
DerivedApp::DerivedApp()
{
}
DerivedApp::~DerivedApp()
{
}
void DerivedApp::Run()
{
app_run = true;
while (app_run) {
ClockUpdate();
}
}
//void DerivedApp::OnClockTime()
//{
// static int counts(0);
// std::cout << "Tick..." << std::endl;
// counts++;
// if (counts >= 10)
// app_run = false;
//}
main.cpp
#include "DerivedApp.h"
class App : public DerivedApp
{
public:
App(){}
~App(){}
};
int wmain(int argc, wchar_t * argv[])
{
App *app = new App();
app->Init();
app->Run();
delete app;
}
Thanks to those who requested a minimal working example, I built it and it works exactly as I had hoped. The complier will complain about no instantiation of the ABC in the App class. If I remove the comments from DerivedApp::OnClockTime() it compiles and runs the way I wish. Obviously my actual code is not following this model as I thought, so now I need to reexamine where I went wrong. Thanks.
There is no keyword in C++ that forces a class to override some method. However, by making OnTimeExpired() pure virtual you're making IClock an abstract class. Any classes deriving from IClock that do not implement OnTimeExpired() will automatically become an abstract class too, thus not allowing you to create objects of these classes. This means that your code as-is is completely legal unless you try to make objects of these classes
class AbstractBase {
public:
virtual void someFunc() = 0; // Purely Virtual
};
class AbstractDerived : public AbstractBase {
public:
void someOtherFunc();
// Still abstract because the following is not declared-defined
// void someFunc() override { ... }
};
class NonAbstractDerivedA : public AbstractBase { // Derived From Base
public:
void someFunc() override { /* do this class's implementation*/ }
};
class NonAbstractDerivedB : public AbstractDerived { // Derived From AbstractDerived
public:
void someFunc() override { /* do this class's implementation*/ }
};
uses:
#include "above"
int main() {
AbstractBase base; // compiler error
AbstractDerived derived; // compiler error
NonAbstractDerivedA derivedA; // should be okay
NonAbstractDerivedB derivedB; // should be okay
return 0;
}
I had written a set of classes to check composition pattern.
Here is my code:
#include <iostream>
#include <string>
#include <list>
#include "InvalidCompositeException.h"
using namespace std;
class Composite;
class Component {
public:
Component() {}
virtual ~Component() {}
virtual string getName() = 0;
virtual int getNetPrice() = 0;
virtual Composite* getComposite() {
try {
throw myEx;
} catch (InvalidCompositeException& e) {
cout<<"Exception: "<<e.what();
}
return 0;
}
**virtual void add(Component* c);
virtual void remove(Component* c);**
private:
};
class Composite : public Component {
public:
Composite():mChildList(new list<Component*>()) {}
virtual ~Composite() {
mChildList->clear();
delete mChildList;
}
virtual string getName() {return "Composite";}
virtual int getNetPrice() {
list<Component*>::iterator i;
int sum = 0;
for(i=mChildList->begin(); i!= mChildList->end(); ++i) {
sum = sum + (*i)->getNetPrice();
}
return sum;
}
virtual void add(Component* c) {
mChildList->push_back(c);
}
virtual void remove(Component* c) {
mChildList->remove(c);
}
private:
list<Component*>* mChildList;
};
class Container: public Composite {
public:
Container() {}
virtual ~Container() {}
string getName() {
cout<<"container"<<endl;
return "container";
}
};
class Line: public Component {
public:
Line(): mNetPrice(50) {}
~Line() {};
int getNetPrice() { return mNetPrice; }
string getName() {
cout<<"line"<<endl;
return "line";
}
private:
int mNetPrice;
};
class Text: public Component {
public:
Text(): mNetPrice(100) {}
~Text() {};
int getNetPrice() { return mNetPrice; }
string getName() {
cout<<"Text"<<endl;
return "Text";
}
private:
int mNetPrice;
};
int main(void) {
Container* c = new Container();
Line* l = new Line();
Text* t = new Text();
c->add(l);
c->add(l);
c->add(t);
cout<<"total price for c is "<<c->getNetPrice();
l->getComposite();
delete t;
delete l;
delete c;
return EXIT_SUCCESS;
}
My code runs fine except when I add those bold lines in my parent class that i receive errors
undefined reference to `vtable for Component' // on this line virtual ~Component() {}
undefined reference to `Component::add(Component*)'
undefined reference to `Component::remove(Component*)'
I have not define virtual functions to be pure. Then why do I receive those errors even if i don't define them in Line and Text Classes. If I dont add those bold declarations my code works fine. And secondly why error on destructor?
Non-pure virtual functions need to have a definition, even if they are never called (so that the linker has something to put in the vtable). Simply add =0 to make your class abstract, or provide empty definitions.
The error with the destructor is a little more involved, but basically the compiler needs to decide in which object file to place the vtable for your polymophic class -- it usually does this wherever the first non-pure, non-inline virtual function is defined (with more complicated rules where there are no such functions). In this case, you're declaring two out-of-line virtual functions, but never defining them, so the compiler never writes the vtable into an object file.
If there's no implementation in the base class, you need to make them abstract with the =0 in the virtual function declaration. Otherwise, the virtual function table for the base class will try to find bodies - without the =0, it figures they must exist, and that will end up pointing at nothing, causing the linker error.
The destructor error is the same thing - it needs that complete table to find the virtual dtor and the table isn't complete.
Consider:
class foo
{
public:
void doit();
};
foo f;
f.doit(); // linker error, doit isn't defined!
What do you think happens if void doit() becomes virtual doit()? Nothing, same error as you have now. However virtual void doit() = 0 by making it pure will resolve the error. A virtual function is like any other, it must have an implementation.
I would like to have a C++ Interface that must be overridden (if this is possible) when inherited. So far, I have the following:
class ICommand{
public:
// Virtual constructor. Needs to take a name as parameter
//virtual ICommand(char*) =0;
// Virtual destructor, prevents memory leaks by forcing clean up on derived classes?
//virtual ~ICommand() =0;
virtual void CallMe() =0;
virtual void CallMe2() =0;
};
class MyCommand : public ICommand
{
public:
// Is this correct?
MyCommand(char* Name) { /* do stuff */ }
virtual void CallMe() {}
virtual void CallMe2() {}
};
I have purposely left how I think the constructor/destructor's should be implemented in ICommand. I know if I remove the comments, it will not compile. Please could someone:
Show me how to declare the constructor/destructor's in ICommand and how they are meant to be used in MyCommand
Have I set things up correctly in ICommand so that MyCommand must override CallMe and CallMe2.
C++ does not allow for virtual constructors. A simple implementation (without the virtual constructor) would look something like this:
class ICommand {
public:
virtual ~ICommand() = 0;
virtual void callMe() = 0;
virtual void callMe2() = 0;
};
ICommand::~ICommand() { } // all destructors must exist
Note that even a pure virtual destructor must be defined.
A concrete implementation would look exactly like your example:
class MyCommand : public ICommand {
public:
virtual void callMe() { }
virtual void callMe2() { }
};
You have a couple of options for the constructor. One option is to disable the default constructor for ICommand, so that subclasses will have to implement a constructor that calls your ICommand constructor:
#include <string>
class ICommand {
private:
const std::string name;
ICommand();
public:
ICommand(const std::string& name) : name(name) { }
virtual ~ICommand() = 0;
virtual void callMe() = 0;
virtual void callMe2() = 0;
};
ICommand::~ICommand() { } // all destructors must exist
A concrete implementation would now look something like this:
class MyCommand : public ICommand {
public:
MyCommand(const std::string& name) : ICommand(name) { }
virtual void callMe() { }
virtual void callMe2() { }
};
I know this one is old, but it is still my first hit on this issue. This is how I would do it.
Interface header foo.h:
#pragma once
#include <memory>
enum class Implementations {Simple, Fancy};
class Foo
{
public:
using Ptr = std::unique_ptr<Foo>;
virtual ~Foo() = default;
virtual void do_it() = 0;
};
Foo::Ptr create_foo(Implementations impl); // factory
Yes I know that "pragma once" is strictly speaking not standard, but it works for me.
Note that nothing is implemented here. There is no constructor: an abstract class can not be instantiated. You get a pointer to the interface through the factory. For the virtual function calls to work, they must be called through a pointer. The virtual destructor is defaulted because it doesn't have to do anything special except polymorphing to the implementation. The factory is a free function. No need to try to make it a static member or something like that. This is not java.
Interface foo.cpp:
#include "foo.h"
#include "foo_impl.h"
Foo::Ptr create_foo(Implementations impl)
{
switch (impl)
{
case Implementations::Simple:
return std::make_unique<Simple_foo>();
case Implementations::Fancy:
return std::make_unique<Fancy_foo>();
default:
return nullptr;
}
}
Here the factory is implemented. Notice that the factory has to know the implementation(s). That is why we don't implement it inline: if it was inline, the interface header would have to include the implementation header, and through it, knowledge of the implementation would "leak out" to the callsite.
The implementation header foo_impl.h:
#pragma once
#include "foo.h"
class Simple_foo : public Foo
{
void do_it() override;
};
class Fancy_foo : public Foo
{
void do_it() override;
};
Nothing special, just override the virtual functions of the interface. Because this exaple is simple, I put both implementations in the same files. In real applications that will be different.
The implementation foo_impl.cpp:
#include "foo_impl.h"
#include <iostream>
void Simple_foo::do_it()
{
std::cout << "simple foo\n";
}
void Fancy_foo::do_it()
{
std::cout << "fancy foo\n";
}
Just implement the functions.
The main.cpp:
#include "foo.h"
int main()
{
auto sf = create_foo(Implementations::Simple);
sf->do_it();
auto ff = create_foo(Implementations::Fancy);
ff->do_it();
return 0;
}
Through the enum we can select the implementation we want. The pointers are of type Foo::Ptr, an alias for std::unique_ptr<Foo>. The callsite has no knowledge of the implementation at all, only the interface.
The output will be as expected:
simple foo
fancy foo
In Delphi we have an option to do a thing like this:
TClass1 = class
procedure Test; virtual;
end;
TClass2 = class(TClass1)
procedure Test; override;
end;
So in code, If I create an instance of TClass2, even if I cast the object like:
TClass1(ObjectClass2).Test;
The application will call the function declared on TClass2.
But in C/C++ I could not find a way to do this.
If I declare some void as virtual and implement the same void in the children class when I do the cast to the parent class it'll not use the implementation of the children class.
Does anyone know how I can reproduce the behavior of Delphi in C/C++ ?
New informations:
These are my files.
---------------------- File Filho.hpp
#ifndef FILHO_HPP
#define FILHO_HPP
#include "Pai.hpp"
class Filho : public Pai {
public:
Filho();
virtual ~Filho();
void metodoX();
};
Filho::Filho() {}
Filho::~Filho() {}
void Filho::metodoX() {
std::cout << "Hello Filho!" << std::endl;
}
#endif
---------------------- File Pai.hpp
#ifndef PAI_HPP
#define PAI_HPP
#include <iostream>
class Pai {
public:
Pai();
virtual ~Pai();
virtual void metodoX();
};
Pai::Pai() {}
Pai::~Pai() {}
void Pai::metodoX() {
std::cout << "Hello Pai!" << std::endl;
}
#endif
---------------------- File Main.hpp
#include "Pai.hpp"
#include "Filho.hpp"
int main() {
Pai pai;
pai.metodoX(); //Here output the msg Hello Pai!
Filho filho;
filho.metodoX(); //Here output the msg Hello Filho!
((Pai) filho).metodoX(); //Here output the msg Hello Pai! , but here if I use the directive 'override' in Delphi, the output will be Hello Filho!. Here is my doubt.
return 0;
}
I'm not a Delphi expert, but I can explain how this stuff behaves in C++.
So in C++, you can have a class that defines a virtual function, which means that if you use a base class pointer/reference to an object, that function can be invoked via dynamic dispatch (i.e. runtime function lookup).
#include <iostream>
class BaseClass
{
public:
virtual void virtFunc() { std::cout << "BaseClass\n"; } // notice the 'virtual' keyword
void nonvirtFunc() { std::cout << "BaseClass\n"; }
};
class SubClass : public BaseClass
{
public:
virtual void virtFunc() { std::cout << "SubClass\n"; }
void nonvirtFunc() { std::cout << "SubClass\n"; }
};
int main()
{
// You need to use base class pointers/references
SubClass sc = SubClass();
BaseClass *bcp = ≻
bcp->virtFunc(); // prints "SubClass"
bcp->nonvirtFunc(); // prints "BaseClass"
// doing it by allocating an object on heap
BaseClass *dbcp = new SubClass();
dbcp->virtFunc(); // prints "SubClass"
dbcp->nonvirtFunc(); // prints "BaseClass"
delete dbcp; // in a real program, you should have a virtual destructor which will be called from this code
BaseClass bc = SubClass();
bc.virtFunc(); // prints "BaseClass", and in more complex objects, slicing occurs
}
New Code You Posted
I see that you updated with your code that does this:
((Pai)filho).metodoX();
So when you do that, you are not using pointers/references to a base class. You are just casting the filho object to a Pai object. This does not result in a polymorphic function call, and instead will just call the Pai::metodoX() function.
If you did this instead:
((Pai*)filho)->metodoX();
It would call Filho's metodoX() polymorphically.
In C++ you would write:
class Class1
{
public:
virtual void Test();
};
class Class2: public Class1
{
public:
virtual void Test();
};
Class1* obj = new Class2();
obj->Test();//calls Class2.Test()
This achieves the same as your Delphi example.
The key is to create the C++ object on the heap and maintain a reference to it, which is of course the only way to do things in Delphi which does not support stack based objects.
TClass1* obj = new TClass2 ;
obj->procedure();
If, TClass1 ( base class) and TClass2 ( derived class ) has hierarchial relationships( i.e., inheritance )
class TClass1
{
public:
virtual void procedure(){} // Assuming procedure's return type is void.
virtual ~TClass1(){}
};
class TClass2 : public TClass1
{
public:
void procedure(){}
};