C++编译报错:Mario类无默认构造函数问题求助
问题:Mario类无默认构造函数导致编译错误
我尝试创建一个存储程序全局通用信息的struct,计划在Mario::init()函数中更新该信息,但编译时出现如下错误:
No default constructor exists for class "Mario"
主文件代码
#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; }
头文件(Mario.hpp)代码
#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
源文件(Mario.cpp)代码
#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); }
注释掉头文件中的以下两行时,程序可正常编译:
M_info& m_info; Mario(M_info& m_info_s) : m_info(m_info_s){}
但取消注释后,主文件会报两个错误:
No default constructor exists for class "Mario"
Local variable not initialized
我试过给成员添加默认值、创建默认构造函数,但均未成功,希望得到解决方法。
解决方案
问题根源有两点:
- 自定义
Mario的构造函数后,C++不会自动生成默认构造函数(无参数的构造函数),而main中Mario m;的写法正是在调用默认构造函数,因此报错。 Mario中的m_info是引用类型,引用必须在对象初始化时就绑定到一个已存在的有效对象,无法默认初始化。
思路1:先创建M_info对象,再传入Mario构造函数(推荐)
修改main函数,先实例化M_info全局信息对象,再用它初始化Mario,完全符合引用的初始化要求:
int main() { sf::RenderWindow window(sf::VideoMode(1920, 1080), "SFML works!"); window.setFramerateLimit(60); M_info global_info; // 先创建全局信息实例 Mario m(global_info); // 用已存在的M_info对象初始化Mario m.init(); // 调用init加载资源 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; }
思路2:给Mario添加默认构造函数(不推荐)
如果一定要使用Mario m;的写法,需要让引用绑定到一个全局或静态的M_info对象,但这种方式可能破坏封装性,且需注意内存生命周期:
修改头文件中的Mario结构:
struct Mario { M_info& m_info; // 辅助函数提供静态全局M_info实例 static M_info& get_global_info() { static M_info info; return info; } // 默认构造函数,绑定到静态全局实例 Mario() : m_info(get_global_info()) {} Mario(M_info& m_info_s) : m_info(m_info_s){} void init(); void update(sf::RenderWindow&); };
这种方式依赖静态对象,仅适合确实需要单一全局实例的场景。
额外提示
- 引用类型的成员变量必须在构造函数的初始化列表中完成绑定,无法在构造函数体内赋值,这也是你之前尝试添加默认值失败的原因。
- 如果
M_info确实是全局通用的,也可以考虑设计成单例模式,但需注意全局变量的初始化顺序问题。
内容的提问来源于stack exchange,提问作者ggjorven
相关产品推荐
相关产品推荐

