1

Basically for some reason new object is wrong type. All source code is on github https://github.com/teuro/sfml-radar. If it's help please fork at will.

I have following class:

#ifndef _VIEW_HPP
#define _VIEW_HPP

#include <iostream>

#include "sfml_drawsurface.hpp"

class View {
protected:
    View(Drawsurface& d) : drawer(d) {
        std::clog << "View::View()" << std::endl;
    }

    Drawsurface& drawer;

    virtual void draw() = 0;
};


#endif

That is base class for all different kind of views. Now I have derived sub-class

#ifndef _GAME_VIEW_HPP
#define _GAME_VIEW_HPP

#include <vector>
#include <iostream>
#include <typeinfo>

#include "view.hpp"
#include "../models/game.hpp"

class Gameview : public View {
public:
    Gameview(Drawsurface& d);
    ~Gameview();
    void draw();
private:
    Drawsurface& drawer;
};

#endif // _GAME_VIEW_HPP

Then abstract class Drawsurface

/**
    * drawsurface base for all graphics pure abstract
    * provide only interface quite high-level
    * 2014/06/02
    * Juha Teurokoski
**/

#ifndef _DRAWSURFACE_HPP
#define _DRAWSURFACE_HPP

#include <string>

#include "../models/point.hpp"

class Drawsurface {
public:
    bool font_loaded;
    virtual void rectangleColor(Point& a, Point& b, unsigned int color) = 0;
    virtual void lineColor(Point& a, Point& b, unsigned int color) = 0;
    virtual void circleColor(Point& a, unsigned int rad, unsigned int color) = 0;
    virtual void trigonColor(Point& a, Point& b, Point& c, unsigned int color) = 0;
    virtual void trigonColor(Point& a, unsigned int size, unsigned int color) = 0;
    virtual void load_font(std::string font) = 0;

    virtual void draw_picture(std::string tiedosto, Point& a, bool center = false) = 0;
    virtual void draw_text(std::string text, Point& a, unsigned int color = 0) = 0;

    virtual int get_fontsize() = 0;
    virtual void flip() = 0;
    virtual void clear_screen() = 0;

    virtual ~Drawsurface() { }
};

#endif

Now if I create new instance of sfml_drawsurface which is sub-class of Drawsurface. For some reason new object is Drawsuface istead of sfml_drawsurface. Below is sfml_drawsurface class.

#ifndef SFML_DRAWSURFACE_HPP
#define SFML_DRAWSURFACE_HPP
/**
    * sfml-drawsurface provides basic drawing, pictures and text
    * require drawsurface
    * 2014/06/02
    * Juha Teurokoski
**/

#include "drawsurface.hpp"

#include <vector>
#include <stdexcept>
#include <iostream>

#include <SFML/Graphics.hpp>

class sfml_drawsurface : public Drawsurface {
public:
    sfml_drawsurface(sf::RenderWindow& window);
    ~sfml_drawsurface();

    void rectangleColor(Point& a, Point& b, unsigned int color);
    void circleColor(Point& a, unsigned int rad, unsigned int color);
    void lineColor(Point& a, Point& b, unsigned int color);
    void trigonColor(Point& a, Point& b, Point& c, unsigned int color);
    void trigonColor(Point& a, unsigned int _size, unsigned int color);

    void draw_picture(std::string tiedosto, Point& a, bool center = false);
    void draw_text(std::string text, Point& a, unsigned int color);
    void load_font(std::string font);
    void clear_screen();

    int get_fontsize();
    void flip();
protected:
private:
    sf::RenderWindow& window;
    sf::Font font;

    sf::Color active;
    sf::Color normal;
};

#endif // SFML_DRAWSURFACE_HPP

I create new object like this:

sfml_drawsurface drawer(window);

this->gameview = new Gameview(drawer);
std::clog << typeid(drawer).name() << std::endl;

And everything seems to be right, because std::clog outout is '16sfml_drawsurface'.

Next place is draw-method then happens something really weird.

Same print is now '11Drawsurface'.

teuro
  • 31
  • 4
  • Your include guards are all [reserved identifiers](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – chris Oct 25 '14 at 14:59
  • The only immediate oddity I see in this code is that none of your *derived* class destructors are declared virtual. Why you do this I cannot say (and its too early and not enough caffeine for me to remember whether it even matters or not). – WhozCraig Oct 25 '14 at 15:06
  • 1
    Most likely, `drawer` goes out of scope before you call `draw`, leaving `gameview` with a dangling reference to the destroyed object. You need to make sure it lasts as long as anything that uses it. – Mike Seymour Oct 25 '14 at 15:21

1 Answers1

1

Looks like Mike had the right idea. From your Program.cpp file you have in your constructor:

Program::Program() {
    Game game;
    ...
    this->gamecontroller = new Gamecontroller(game);  //Probably also bad

    sfml_drawsurface drawer(window);
    this->gameview = new Gameview(drawer);  
}

The problem is that drawer ceases to exist once the constructor is finished leaving you with a dangling reference and undefined behaviour. Looks like you may have the same problem with the game variable.

Solution is to not have them as local variables but as either class members (preferred) or dynamically allocated (it depends how long you need to have them around).

uesp
  • 6,194
  • 20
  • 15
  • Yep solution was to move gamecontroller, game and gameview out of constructor. Now I pass them while I create new program object. – teuro Oct 25 '14 at 16:17