Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem with initializing an object with a constructor in another class constructor

this is my first question. I’m a beginner so bear with me.

So, right here:

TitleScreen::TitleScreen(ScreenManager& sm) :
    sm(sm),

// The problem lies here
    play({ 1500.f, 400.f }, tsButtons, "Play", "fonts/OldSchoolAdventures-42j9.ttf"),
    options({ 1500.f, 500.f }, tsButtons, "Options", "fonts/OldSchoolAdventures-42j9.ttf"),
    quit({ 1500.f, 600.f }, tsButtons, "Quit", "fonts/OldSchoolAdventures-42j9.ttf")
{
    if (!tsButtons.loadFromFile("fonts/OldSchoolAdventures-42j9.ttf"));
    {
        throw "Error: Font not found.";
    }

}

There’s an error for the Button instances "play", "options", and "quit": "no instance of constructor ‘Button::Button’ matches the argument list" that use a custom constructor:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Button(const sf::Vector2f&& position, sf::Font& font, const std::string& text, std::string& fontFile);

First, the error was "expected a ‘)’".

The Button constructor seems and the initializations seem to add up, but it still gives me an error.

The code that I think is necessary to know what’s going on:

TitleScreen.h:

#pragma once
#include "Screens.h"
#include "Button.h"
#include "ScreenManager2.h"
#include <SFML/Graphics.hpp>

class TitleScreen : public Screens
{
private:
    Button play;
    Button options;
    Button quit;

    Font tsButtons;

    ScreenManager& sm;

public:
    TitleScreen(ScreenManager& sm);

    void display(sf::RenderWindow& window);

    void update(sf::Time dt);

    void handleInput(sf::Event& event);
};

In TitleScreen.cpp:

TitleScreen::TitleScreen(ScreenManager& sm) :
    sm(sm),

// The problem lies here
    play({ 1500.f, 400.f }, tsButtons, "Play", "fonts/OldSchoolAdventures-42j9.ttf"),
    options({ 1500.f, 500.f }, tsButtons, "Options", "fonts/OldSchoolAdventures-42j9.ttf"),
    quit({ 1500.f, 600.f }, tsButtons, "Quit", "fonts/OldSchoolAdventures-42j9.ttf")
{
    if (!tsButtons.loadFromFile("fonts/OldSchoolAdventures-42j9.ttf"));
    {
        throw "Error: Font not found.";
    }

}


void TitleScreen::display(sf::RenderWindow& window)
{
    // TODO: add BG
    play.display(window);
    options.display(window);
    quit.display(window);
}

void TitleScreen::update(sf::Time dt)
{
    
}

void TitleScreen::handleInput(sf::Event& event)
{
    play.handleInput(event);
    options.handleInput(event);
    quit.handleInput(event);
}

Button.h:

#pragma once

#include <SFML/Graphics.hpp>
#include <string>

class Button
{
public:
    Button(const sf::Vector2f& size, const sf::Vector2f& position, sf::Font& font, const std::string& text, std::string& fontFile);
// This is the constructor I'm trying to use:
    Button(const sf::Vector2f&& position, sf::Font& font, const std::string& text, std::string& fontFile);

    bool handleInput(const sf::RenderWindow& window);

    void display(sf::RenderWindow& window);

    bool getPressed();

private:
    sf::RectangleShape rect;
    sf::Text label;
    bool pressed = false;
    sf::Color skyBlue;
};

Button.cpp:

#include "Button.h"

Button::Button(const sf::Vector2f&& position, sf::Font& font, const std::string& text, std::string& fontFile)
{
    if (!font.loadFromFile(fontFile))
    {
        throw "Error: Font not found";
    }

    font.loadFromFile(fontFile);

    skyBlue.r = 135;
    skyBlue.g = 206;
    skyBlue.b = 235;
    skyBlue.a = 100;

    rect.setSize(sf::Vector2f(label.getGlobalBounds().width, label.getGlobalBounds().height));
    rect.setPosition(position);
    rect.setFillColor(sf::Color::Transparent);

    label.setFont(font);
    label.setString(text);
    label.setCharacterSize(72);
    label.setFillColor(sf::Color::White);
    label.setPosition(position);
    label.setOutlineThickness(2.f);
    label.setOutlineColor(skyBlue);
}

Button::Button(const sf::Vector2f& size, const sf::Vector2f& position, sf::Font& font, const std::string& text, std::string& fontFile)
{
    font.loadFromFile(fontFile);

    skyBlue.r = 135;
    skyBlue.g = 206;
    skyBlue.b = 235;
    skyBlue.a = 100;

    rect.setSize(size);
    rect.setPosition(position);
    rect.setFillColor(sf::Color::Transparent);

    label.setFont(font);
    label.setString(text);
    label.setCharacterSize(72);
    label.setFillColor(sf::Color::White);
    label.setPosition(position.x + (size.x - label.getGlobalBounds().width) / 2,
        position.y + (size.y - label.getGlobalBounds().height) / 2);
    label.setOutlineThickness(2.f);
    label.setOutlineColor(skyBlue);
}

bool Button::handleInput(const sf::RenderWindow& window)
{
    sf::Vector2i mousePos = sf::Mouse::getPosition(window);
    if (rect.getGlobalBounds().contains(static_cast<sf::Vector2f>(mousePos)))
    {
        rect.setFillColor(skyBlue);
        if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            pressed = true;
            return true;
        }
    }
    else
    {
        rect.setFillColor(sf::Color::Transparent);
    }

    return false;
}

void Button::display(sf::RenderWindow& window)
{
    window.draw(rect);
    window.draw(label);
}

bool Button::getPressed()
{
    return pressed;
}

Another error I have is that in the TitleScreen’s handleInput function, I pass an event but it says "no suitable user-defined conversion from sf::Event to const sf::RenderWindow exists", idk why.

Also, if it wasn’t apparent, I’m using SFML.

I’ve tried using chat GPT to answer my question on how to fix it. It’s told me to replace Vector2f with curly braces (which I did, as you can see), and that worked, but it’s not helping me fix it, as in it’s telling me wrong things, like the constructor I’m trying to use has three arguments when it has four (it has some bugs still you know).

I haven’t tried anything with that as I’m not focused on it more than the first problem. I think it’ll fix itself once everything comes together.

Thanks for bearing through.

>Solution :

    Button(
          // ...
            std::string& fontFile);

The fourth parameter to the constructor is a reference to a std::string.

play(
    // ...
      "fonts/OldSchoolAdventures-42j9.ttf"),

The actual attempted value getting passed in is a literal character string. It is not a std::string. It is a const char (&)[ (whatever its size is)].

This kind of a conversion, from a literal character string to a std::string is possible, there is an implicit constructor and a conversion for it, but it produces a temporary object.

This is how C++ works: implicit conversions result in temporary objects, when used in this kind of a context. In C++ a reference cannot be bound to a temporary object. Only a reference to a const object can.

You must either change the constructor parameter to a std::string, or a const std::string &, or obtain an actual, living, breathing std::string object from somewhere else, in order to pass it by reference.

I’ve tried using chat GPT

This is a bot that has no empirical understanding of C++, and is not a replacement for a C++ textbook, unfortunately.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading