Search code examples
c++initializationdefault-constructor

Getting "No default constructor exists for class" error


I have been trying to make a struct with general information I want to use throughout my program. I'm updating this information in my Mario::init() function, but now its giving me this error:

No default constructor exists for class "Mario"

My main file:

#include <SFML/Graphics.hpp>
#include <iostream>
    
#include "Mario.hpp"
    
int main()
{
    sf::RenderWindow window(sf::VideoMode(1920, 1080), "SFML works!");
    window.setFramerateLimit(60);
    
    Mario m;
    
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed) window.close();
        }
    
        window.clear();
        //m.update(window);
        window.display();
    }
    
    return 0;
}

My header file:

#include <SFML/Graphics.hpp>
    
#ifndef MARIO_HPP
#define MARIO_HPP

struct M_info {
    sf::Texture textureMario;
    sf::Sprite mario;
    int x = 100;
    int y = 100;
    bool Initialized = false;
};
    
struct Mario {
    M_info& m_info;
    
    Mario(M_info& m_info_s) : m_info(m_info_s){}
    
    void init();
    void update(sf::RenderWindow&);
};
    
#endif

My resource file:

#include "Mario.hpp"
#include <SFML/Graphics.hpp>
#include <iostream>

void Mario::init()
{
    if(!m_info.textureMario.loadFromFile("C:\\Users\\beheerder\\source\\repos\\Mario\\images\\mario.png")) std::cout << "FAILED TO LOAD MARIO.";
    m_info.mario.setTexture(m_info.textureMario);
    std::cout << "Loaded texture\n";
}

void Mario::update(sf::RenderWindow& window)
{
    window.draw(m_info.mario);
}

Pretty much all the code is working when I comment out these two lines in my header file:

M_info& m_info;
Mario(M_info& m_info_s) : m_info(m_info_s){}

In the main file, it's giving me these errors when I uncomment them, though:

No default constructor exists for class "Mario"

Local variable not initialized

I'm quite lost here. I've searching and searching and I can't find a solution, so I decided to post on here. I hope someone can help a newbie out.

I've tried to add default values somehow, but couldn't find out how to do it properly, and tried to find out a way to create a default constructor somehow.

Honestly, I'm lost.


Solution

  • In C++ you are advised to initialize your objects with constructors rather than using functionalities like 'Init', when compiler sees your object instantiation it will call the used constructor, if your not using any constructor it will call the 'default' constructor, default constructor is the constructor with no input parameters, then it will try to initialize the objects inside your class and if they themselves have objects in them it will call their objects constructors too, and when an object goes out of scope it will call the destructor, its called RAII. this way compiler will help to prevent troubles like memory leak and deadlocks(in multi-threading).

    learn more: https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization

    structs and classes are basically the same only difference is struct's default data and method access is public while for class is private, While creating and object of 'class' Mario, compile will create the object using constructors, however you are using reference in your class which requires static in place initialization, that's the feature of references one of the reasons they are assumed to be safer than pointers, and if you don't initialize that reference while your creating 'mario' object, compiler will give you an error. You should always initialize your references while creating them, because creating the 'mario' object requires all of its member objects to be initialized as well.

    int* pint; //ok
    int& rint; //illegal, references must be initialized
    

    In your code case you must either create and instance of M_info with your class or create and instance of M_info and pass that to Mario's constructor.

    M_info info;
    //initialize your info object
    Mario m(info); // pass info to mario class 
    

    Or you can take this approach.

    struct Mario {
    M_info m_info; //create the object by this struct
    
    Mario() = default;
    
    void init();
    void update(sf::RenderWindow&);
    };
    

    Note that when you create the mario object in this way compiler will call the default constructor of info first, then mario. if you provide the constructor for both and use them by calling them like I did in the code this way you'll initialize the object with the information you want.

    Read more: https://isocpp.org/wiki/faq/references

    You can also read:

    https://www.learncpp.com/cpp-tutorial/welcome-to-object-oriented-programming/ https://www.learncpp.com/cpp-tutorial/lvalue-references/