So it is my understanding that to make a class abstract in c++ you have to create one, just one, pure virtual method in that class. In my code i create an abstract GameObject class, which is inherited by my Player class, but the problem is i get errors in my Player.cpp saying error LNK2001: unresolved extrenal symbol "public:virtual void__thiscall GameObject::Load(void)" (?Load#GameObject##UAEXXZ) for every method except the initialise, and this gets fixed when i set them all = 0, im just wondering why
// Abstract class to provide derived classes with common attributes
#include <SDL.h>
#include "AnimationManager.h"
#include "Debug.h"
#include "InputHandler.h"
class GameObject
{
public:
virtual void Initialise() = 0;
virtual void Load();
virtual void HandleEvents();
virtual void Update();
virtual void Draw();
Vector2D* position;
int currantFrame;
SDL_Renderer* renderer;
float speed;
bool alive;
};
#include "GameObject.h"
class Player : public GameObject
{
public:
virtual void Initialise();
virtual void Load();
virtual void HandleEvents();
virtual void Update();
virtual void Draw();
Player(SDL_Renderer* r);
~Player();
};
#include "Player.h"
Player::Player(SDL_Renderer* r)
{
renderer = r;
}
Player::~Player()
{
}
void Player::Initialise()
{
position = new Vector2D(10, 10);
currantFrame = 0;
}
void Player::Load()
{
TheAnimationManager::Instance()->load("Assets/circle.png", "player", renderer);
}
void Player::HandleEvents()
{
SDL_Event event;
if (SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_a:
DEBUG_MSG("A Pressed");
position->m_x -= 10;
break;
case SDLK_d:
DEBUG_MSG("D Pressed");
position->m_x += 10;
break;
}
break;
}
}
}
void Player::Update()
{
Vector2D* p = TheInputHandler::Instance()->GetMousePosition();
DEBUG_MSG(p->GetY());
DEBUG_MSG(p->GetX());
currantFrame = int(((SDL_GetTicks() / 100) % 4));
}
void Player::Draw()
{
TheAnimationManager::Instance()->Animate("player", (int)position->GetX(), (int)position->GetY(), 90, 82, 0, currantFrame, renderer, SDL_FLIP_NONE);
}
Every virtual method which might be called through a base class pointer that isn't pure virtual needs to have an implementation.
You seem to have a backwards idea of how abstract/virtual works. You don't choose to make a class abstract, why would you? You choose to make a member function pure virtual, because there is no sensible implementation for it. Then, as a consequence of having a pure virtual function, the class becomes abstract.
The class becoming abstract does not mean that every one of its functions suddenly becomes pure virtual.
Your error is a linker error. The linker was looking for the implementation of the GameObject::Load function, which you didn't provide. If you mark the function as pure virtual, the linker won't look for an implementation.
Some compilers require that for each signature the virtual keyword would specified only once, in the base class. Try this:
class GameObject
{
public:
virtual void Initialise() = 0;
virtual void Load() = 0;
virtual void HandleEvents() = 0;
virtual void Update() = 0;
virtual void Draw() = 0;
...
};
class Player : public GameObject
{
public:
void Initialise();
void Load();
void HandleEvents();
void Update();
void Draw();
...
};
if you don't need the public GameObject::Initialise method be pure virtual, at least give it an empty body, like this
class GameObject
{
public:
void Initialise() {}
...
};
Another conjecture: do you have, by any chance, any instantiations of GameObject in your code? Do you have something like this:
GameObject go;
or something like this:
void foo( GameObject go );
or something like this:
GameObject bar();
or something like this:
vector<GameObject> all_my_objects;
Related
As the title says I have the following "base" class that user can extend:
class BaseScene
{
private:
bool sceneloop = false;
public:
virtual void Start();
virtual void EventHandler(SDL_Event event);
virtual void Update();
virtual void Draw();
void _toggleLoopMode() { sceneloop = !sceneloop; }
bool _sceneloop() { return sceneloop; }
};
My problem is I can't know what name, the user, choose for his classes so how I can call a known method (like Start or EventHandler) from my main class inside an unknown class?
An example of a class that is unknown to me but well-known to the user can be:
class SomeFunnyRandomName : public BaseScene
{
public:
void Start();
void Eventhandler(SDL_Event event);
void Update();
void Draw();
};
So form the main class I need to call Start() inside "SomeFunnyRandomName" without:
SomeFunnyRandomName sfrn = new SomeFunnyRandomName();
If you can include the code it will be very helpful (but not required).
You take a reference or pointer to BaseScene, and call the methods on that. The caller passes an instance of their derived class.
class UsesScene {
BaseScene & scene;
public:
UsesScene(BaseScene & scene) : scene(scene) {}
void doStuff() { scene.Start(); scene.Update(); }
/*... etc*/
};
int main() {
SomeFunnyRandomName scene;
UsesScene usesScene(scene);
usesScene.doStuff();
}
I'm trying to create a state engine in my game for the different screens. id start screen, maybe a file chooser in the future, overworld map, menu screen, etc. But when I forward declare the class it says there are no constructors.
GameState.h:
#pragma once
class GameState
{
public:
virtual ~GameState() {}
virtual void Update() {}
virtual void HandleEvents() {}
virtual void Draw(Graphics& gfx) {}
GameState* getCurrentState()
{
return currentState;
}
void ChangeState(GameState* state)
{
currentState = state;
}
protected:
SDL_Renderer* renderer;
GameState* currentState;
};
GameStates.h
#pragma once
#include "GameState.h"
#include "Texture.h"
#include "Keyboard.h"
class TitleGameState;
class IntroGameState : public GameState
{
public:
IntroGameState(SDL_Renderer* renderer, KeyboardClient& kbd)
:
kbd(kbd)
{
background = new Texture("red.png", renderer);
this->renderer = renderer;
}
~IntroGameState() {}
void HandleEvents()
{
while (!kbd.KeyEmpty())
{
KeyEvent e = kbd.ReadKey();
switch (e.GetCode())
{
case SDLK_RETURN:
if (e.IsPress())
{
currentState = new TitleGameState(renderer, kbd);
}
break;
}
}
}
void Logic() {}
void Draw(Graphics& gfx)
{
background->Draw(0, 0, gfx);
}
private:
Texture* background;
KeyboardClient& kbd;
};
class TitleGameState : public GameState
{
public:
TitleGameState(SDL_Renderer* renderer, KeyboardClient& kbd)
:
kbd(kbd)
{
background = new Texture("blue.png", renderer);
}
~TitleGameState() {}
void HandleEvents()
{
while (!kbd.KeyEmpty())
{
KeyEvent e = kbd.ReadKey();
switch (e.GetCode())
{
case SDLK_RETURN:
if (e.IsPress())
{
printf("OK");
}
break;
}
}
}
void Logic() {}
void Draw(Graphics&gfx)
{
background->Draw(0, 0, gfx);
}
private:
Texture* background;
KeyboardClient& kbd;
};
I define the class right afterwards, and I know I can just move it above IntroGameState, however when I implement the menu game state, it will go back and forth between the menu state and the overworld state. How can I get around this?
Compiler Error:
error C2514: 'TitleGameState' : class has no constructors
File: gamestates.h
Line: 28
Line 28 is this line of code:
currentState = new TitleGameState(renderer, kbd);
The error on the line currentState = new TitleGameState(renderer, kbd); is because the compiler has yet to see the constructor for the class. It doesn't know how to compile this code.
If you forward declare the class class TitleGameState; all you can declare is pretty much a pointer TitleGameState*.
To compile the code you have, you need to define the class before using. Note: defining the class does not mean defining all the methods as well. A class definition consists of the method and member declarations.
class TitleGameState : public GameState
{
public:
TitleGameState(SDL_Renderer*, KeyboardClient&);
~TitleGameState();
void HandleEvents();
// ...
};
class IntroGameState : public GameState
{
// ...
}
After the definition of the classes, you can then define the member functions;
/*inline*/ void TitleGameState::HandleEvents()
// inline is needed if the method is defined in a header file
// to help avoid linker errors
{
// ...
}
I am making a program that solves a number of similar problems.
I am starting with a class that looks like (for example):
class problem {
void init();
void solve();
int print_result();
}
but then I would like to extend this class to different problems:
class problem_A : problem {
void init();
void solve();
void print_result();
}
class problem_B : problem {
void init();
void solve();
void print_result();
}
...
But in the main interface I would like to have a single object for either of the problems (A, B, ...) and handle them like:
obj.init();
obj.solve();
obj.print_result();
How do I achieve this? What type should obj be?
If you always want to call init() then solve() then print_result(), it's best to wrap this up in the (for C++) awkwardly named Template Method Pattern:
class problem {
public:
virtual ~problem() = default;
void run() {
init();
solve();
print_result();
}
protected:
virtual void init() = 0;
virtual void solve() = 0;
virtual void print_result() = 0;
};
And then each of your explicit problems just have to provide implementations for those functions:
class problem_A : public problem {
protected:
void init() override { .. }
void solve() override { .. }
void print_result() override { .. }
};
problem* p = new problem_A(..);
p->run(); // inits, solves, and prints the results for problem A
You stick with your original class, but make the methods pure virtual
class problem {
virtual void init() = 0;
virtual void solve() = 0;
virtual int print_result() = 0;
}
Then you can override these functions in the derived classes
class problem_A : problem {
virtual void init() override;
virtual void solve() override;
virtual void print_result() override;
}
Then you can make your object as follows:
problem* obj = new problem_A;
obj->init();
obj->solve();
obj->print_result();
This will invoke problem_A's methods, but you can use a pointer to the base class problem. Obviously make sure you clean up the memory
delete obj;
Or use smart pointers
std::unique_ptr<problem> = std::unique_ptr<problem>(new problem_A);
I'm not happy with the question title, but I couldn't describe it well. I'm putting implementation in the class declarations for sake of brevity.
I have a class like this:
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<sf::Shape> shape;
}
sf::Shape is an abstract class. Then I have a derived class like so:
class Brick : VisibleObject {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
std::dynamic_pointer_cast<sf::RectangleShape>(shapes).get()->setSize(newSize);
}
}
sf::RectangleShape() is a concrete class that inherits from sf::Shape and setSize() is defined for it, not sf::Shape, which is why I need to cast.
Of course, I need to do some error handling, in the case that the dynamic cast fails and returns an empty shared_ptr.
I'm doing this because I wanted to be able to define the draw method just once, since in this simple game, every object will draw their member this way. Originally I left the shape out of the base class, and e.g. Brick would just have its own private sf::RectangleShape that could get instantiated on the stack; which was clean, but then the draw method had to be re-written for each object type.
This works, but is uglier to work with and introduces heap allocation. I also have shared_ptr overhead (I would have used unique_ptr, but I needed dynamic casting).
Is this the most appropriate way of doing what I'm trying to do?
It might be preferable to keep the interface an interface, and not start mandating implementation details. So just have an empty base class like so:
class VisibleObject
{
public:
~VisibleObject() {}
virtual void draw(sf::RenderWindow & window) = 0;
virtual void setSize(sf::Vector2f const & size) = 0;
};
You can stick the shape storage into the concrete class that implements this interface.
Moreover, Shape should provide a virtual resize method:
class Shape
{
public:
virtual ~Shape() {}
virtual void resize(sf::Vector2f const & size) = 0;
};
Now you can make, say, a VisibleShapeObject as an intermediate base class:
class VisibleShapeObject : public VisibleObject
{
public:
virtual void draw(sf::RenderWindow & window) override final
{
window.draw(*shape_);
}
virtual void setSize(sf::Vector2f const & size) override final
{
shape_->resize(size);
}
protected:
std::shared_ptr<Shape> shape_; // or unique_ptr<Shape>
};
Instead of mandating storage in std::shared_ptr<sf::Shape>, why not simply introduce a means of retrieving an sf::Shape& from the concrete class?
class VisibleObject {
virtual sf::Shape& getShape() = 0;
public:
void draw(sf::RenderWindow& rw) {
rw.draw(getShape());
}
virtual void setSize(sf::Vector2f) = 0;
};
class Brick : VisibleObject {
sf::RectangleShape shape;
sf::Shape& getShape() override { return shape; }
public:
void setSize(sf::Vector2f newSize) override {
shape.setSize(newSize);
}
};
It seems ridiculous to store via a pointer to base, introducing indirections and downcasts and reference count overhead, when you could just store a plain old member. In fact, if I'm understanding the problem correctly, you could probably use a template to generate concrete classes and avoid a lot of boilerplate:
class VisibleObject {
public:
virtual ~VisibleObject() {}
virtual void draw(sf::RenderWindow&) = 0;
virtual void setSize(sf::Vector2f) = 0;
};
template <typename Shape>
class VisibleConcreteObject : public VisibleObject {
Shape shape;
public:
void draw(sf::RenderWindow& rw) override /* final? */ {
rw.draw(shape);
}
void setSize(sf::Vector2f newSize) override /* final? */ {
shape.setSize(newSize);
}
};
typedef VisibleConcreteObject<sf::RectangleShape> Brick;
You haven't shared everything you are trying to do, but this it one way:
template<ShapeT>
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<ShapeT> shape;
void reset(ShapeT* shape) {
this->shape = shape;
}
}
class Brick : VisibleObject<sf::RectangleShape> {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
shape->setSize(newSize);
}
}
There may be reasons why this doesn't work for you, but without more insight, I couldn't guess at what.
I have an abstract class defined as follows:
class AnimatedDraw
{
public:
virtual void Draw(sf::RenderWindow &window) = 0;
virtual void Draw(sf::RenderWindow &window, sf::Shader shader) = 0;
virtual void Update(sf::Clock &time) = 0;
};
I'm trying to inherit from it into another class defined as follows:
class ScreenLayer explicit : public AnimatedDraw
{
public:
ScreenLayer(void);
virtual void Draw(sf::RenderWindow &window) override; //I'll need to be able to override these again in subclasses
virtual void Draw(sf::RenderWindow &window, sf::Shader &shader) override;
virtual void Update(sf::Clock &clock) override;
~ScreenLayer(void);
};
The source file is empty functions right now and is as follows:
#include "ScreenLayer.h"
ScreenLayer::ScreenLayer(void)
{
}
void ScreenLayer::Draw(sf::RenderWindow &window)
{
}
void ScreenLayer::Draw(sf::RenderWindow &window, sf::Shader &shader)
{
}
void ScreenLayer::Update(sf::Clock &clock)
{
}
ScreenLayer::~ScreenLayer(void)
{
}
I'm doing something wrong, as my compiler (VC2010) produces several errors, including complaining it can't find ScreenLayer in the ScreenLayer.cpp file, and several about this line class ScreenLayer explicit : public AnimatedDraw I haven't tried to use explicit overrides before, but according to the C++0x article on wikipedia, that is how you do it. Does VC2010 not support explicit overrides, or did i mess something else up?
Thanks in advance
Apparently it doesn't support explicit. It's fine because it probably won't go to the standard.