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.
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 have the following interfaces
template <typename string_t>
class PluginManager
{
public:
virtual ~PluginManager() = default;
virtual Plugin<string_t>* findPlugin(string_t const&plugin_uuid) const = 0;
virtual Plugin<string_t>* loadPlugin(string_t const&plugin) = 0;
virtual void unloadPlugin(string_t const&plugin) = 0;
virtual void registerPlugin(Plugin<string_t> *plugin) = 0;
virtual void unregisterPlugin(Plugin<string_t> *plugin) = 0;
virtual void sigPluginLoaded() = 0;
};
template <typename string_t>
class Plugin
{
public:
virtual ~Plugin() = default;
virtual string_t uuid() const = 0;
virtual void setManager(PluginManager<string_t> *manager) = 0;
};
I also have two classes that implement these interfaces
class Core : public QObject, public PluginManager<QString>
{
Q_OBJECT
using string_t = QString;
using map_t = QMap<string_t, ad::Plugin<string_t>*>;
private:
Core();
public:
static Core* instance();
Plugin<string_t>* findPlugin(string_t const&plugin_uuid) const override;
Plugin<string_t>* loadPlugin(string_t const&plugin) override;
void unloadPlugin(string_t const&plugin) override;
void registerPlugin(Plugin<string_t> *plugin) override;
void unregisterPlugin(Plugin<string_t> *plugin) override;
signals:
void sigPluginLoaded();
private:
map_t __plugin_map;
static Core* __instance;
};
class SettingsApplierPlugin : public QObject, public ad::Plugin<QString>
{
Q_OBJECT
public:
SettingsApplierPlugin();
QString uuid() const override;
void setManager(ad::PluginManager<QString> *manager) override;
public slots:
void updateSettings() const;
private:
PluginManager<QString> *__plg_mgr;
};
And finally the function implementation that neccessary for this question
void Core::registerPlugin(ad::Plugin<Core::string_t> *plugin)
{
plugin->setManager(this);
__plugin_map.insert(plugin->uuid(), plugin);
emit sigPluginLoaded();
}
The problem
When I debug the code (I use VSCode with gdb 8.2.91 and Ubuntu 19.04) it behaves strangely. When I step into the plugin->setManager(this) (the plugin in this point is an instance of class SettingsApplierPlugin) the debugger shows the line of the declaration of that class and after one more step-into, it shows the line of the destructor of the Plugin class.
Notice
The image changes, when I remove the QObject class from bases of SettingsApplierPlugin and the Q_OBJECT macro from the class definition, everything works fine and debugger enters into the function correctly.
Note 1
The class SettingsApplierPlugin comes from a shared library and the class Core comes from another shared library.
Note 2
All string_ts are typedefs -> using string_t = QString.
My restrictions
I want to derive from QObject because I want to use the provided signal-slot mechanism.
The question
Can anybody explain the behavior and suggest a solution to this problem?
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.
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;