Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Errors in C++ with Abstract Class and SFML  (Read 2225 times)

0 Members and 1 Guest are viewing this topic.

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Errors in C++ with Abstract Class and SFML
« on: February 22, 2019, 06:06:46 pm »
So I have been working with a tutorial using Xcode, C++, and SFML (Link to Tutorial Website)

I built the code and it worked perfectly. Then, I went through and changed the names of a few of the classes (from lower case to upper case). I went through and built everything to make sure i had changed everything i needed to and i did. Then, when i built and ran the program, i got the follow two errors:

Quote
Field type 'GUI' is an abstract class
and
Quote
Allocating an object of abstract class type 'GUI'

I know that an abstract class contains a "virtual" function, which GUI does, but why would the error be caused if i havent touched the function at all? I guess I just dont really understand what is causing the error, nor do i know how to fix it.

Here is the code for the GUI class:

Quote
class GUI : public sf::Transformable, public sf::Drawable {

private:

/* If true the menu entries will be horizontally, not vertically, adjacent */
bool horizontal;

GUIStyle style;

sf::Vector2f dimensions;

int padding;

public:

std::vector<GUIEntry> entries;

bool visible;

/* Constructor */
GUI(sf::Vector2f dimensions, int padding, bool horizontal, GUIStyle& style, std::vector<std::pair<std::string, std::string>> entries) {

    visible = false;
    this->horizontal = horizontal;
    this->style = style;
    this->dimensions = dimensions;
    this->padding = padding;

    /* Construct the background shape */
    sf::RectangleShape shape;
    shape.setSize(dimensions);
    shape.setFillColor(style.bodyCol);
    shape.setOutlineThickness(-style.borderSize);
    shape.setOutlineColor(style.borderCol);

    /* Construct each gui entry */
    for(auto entry : entries) {

        /* Construct the text */
        sf::Text text;
        text.setString(entry.first);
        text.setFont(*style.font);
        text.setFillColor(style.textCol);
        text.setCharacterSize(dimensions.y-style.borderSize-padding);

        this->entries.push_back(GUIEntry(entry.second, shape, text));

    }

}

sf::Vector2f GetSize();

/* Return the entry that the mouse is hovering over. Returns
 * -1 if the mouse if outside of the Gui */
int GetEntry(const sf::Vector2f mousePos);

/* Change the text of an entry */
void SetEntryText(int entry, std::string text);

/* Change the entry dimensions */
void SetDimensions(sf::Vector2f dimensions);

/* Draw the menu */
virtual void Draw(sf::RenderTarget& target, sf::RenderStates states) const;

void Show();

void Hide();

/* Highlights an entry of the menu */
void Highlight(const int entry);

/* Return the message bound to the entry */
std::string Activate(const int entry);
std::string Activate(const sf::Vector2f mousePos);

};


And here is the line where the error is (the underlined GUI is where the error is):
Quote
this->guiSystem.emplace("rightClickMenu", GUI(sf::Vector2f(196, 16), 2, false, this->game->stylesheets.at("button"),
    {
        std::make_pair("Flatten $"          + this->game->tileAtlas["grass"].GetCost(), "grass"),
        std::make_pair("Forest $"           + this->game->tileAtlas["forest"].GetCost(), "forest" ),
        std::make_pair("Residential Zone $" + this->game->tileAtlas["residential"].GetCost(), "residential"),
        std::make_pair("Commercial Zone $"  + this->game->tileAtlas["commercial"].GetCost(), "commercial"),
        std::make_pair("Industrial Zone $"  + this->game->tileAtlas["industrial"].GetCost(), "industrial"),
        std::make_pair("Road $"             + this->game->tileAtlas["road"].GetCost(), "road")
    }));

Anyways, the question I have is what is causing this error and how do I fix it?

Thank you!

G.

  • Hero Member
  • *****
  • Posts: 1592
    • View Profile
Re: Errors in C++ with Abstract Class and SFML
« Reply #1 on: February 22, 2019, 06:44:21 pm »
sf::Drawable::draw
This is a pure virtual function that has to be implemented by the derived class to define how the drawable should be drawn.
You need to implement the draw method. You can implement it empty if you want.

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Errors in C++ with Abstract Class and SFML
« Reply #2 on: February 22, 2019, 06:51:45 pm »
Ok, so if i understand you correctly, I need to have the draw() function be somewhere? I have the following in the GUI.cpp

Quote
void GUI::Draw(sf::RenderTarget& target, sf::RenderStates states) const {

    if(!visible) return;

    /* Draw each entry of the menu */
    for(auto entry : this->entries) {
   
        /* Draw the entry */
        target.draw(entry.shape);
        target.draw(entry.text);
    }

    return;
}

is that what you mean by implement?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10823
    • View Profile
    • development blog
    • Email
Re: Errors in C++ with Abstract Class and SFML
« Reply #3 on: February 22, 2019, 06:58:55 pm »
Ah the issue is that the function interface needs to be lower-case.
You can't just rename it, as it won't implement the drawable interface anymore.

But the draw function doesn't have to public, so you could still define your class' functions as CamelCase, while implementing the draw(...) function as protected.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Errors in C++ with Abstract Class and SFML
« Reply #4 on: February 22, 2019, 07:23:53 pm »
Ok, so to understand, because it is "overriding" the draw function of drawable, it has to be lowercase to match that function?

also, i changed it and built it and it worked, but now the compiler gets this error:

Quote
/clang:-1: linker command failed with exit code 1 (use -v to see invocation)

is that related to the recent change I made?

Edit: Here is more info from the error:

Quote
ld: warning: directory not found for option '-L/usr/local/lib/'
Undefined symbols for architecture x86_64:
  "tileTypeToStr(TileType)", referenced from:
      GameStateEditor::Update(float) in GameStateEditor.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Thanks!

EDIT:

I fixed it, i looked more closely at the log and found the source of the problem!
« Last Edit: February 22, 2019, 08:19:54 pm by TheOnlyWRT »

 

anything