首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SFML C++:神秘的错误发生在我的软件中,可能与<iostream>和头文件有关?

SFML C++:神秘的错误发生在我的软件中,可能与<iostream>和头文件有关?
EN

Stack Overflow用户
提问于 2020-12-06 10:02:33
回答 1查看 73关注 0票数 1

我正在制作一个项目,为了保持它的组织性,我创建了一个名为clude.h的头文件,它将存储所有的全局变量,并包括。昨天它起了作用,但今天它给了我一些奇怪的错误,我找不到它们的答案。

代码语言:javascript
复制
#include <SFML/Graphics.hpp>
#include <iostream>
#include <stdio.h>

enum GameModes { AgainstComputer, AgainstPlayer, AgainstPc, GameModeScreen }; <- error: C2011: enum 
                                                                                 type redefinition
/*
    enum explanation:
        0 = play against AI
        1 = play online against player
        2 = play locally against a friend
        3 = open the screen showing game modes
*/

// font name
std::string fontName = "Arvo-BoldItalic.ttf"; <- error: C2374: redefinition; multiple initialization

这是包含头的代码,它有两个错误,说明我初始化了变量两次,尽管我没有。

与之相关的其他缺陷在正常功能中:

代码语言:javascript
复制
GameModes welcomeWindow(sf::RenderWindow &window, sf::Event event)
{
    sf::Font font;

    if (!font.loadFromFile("C:\\chess\\Fonts\\" + fontName)) <- error: C2088: illegal for class 
                                                                (where is there a class involved?)
    {
        std::cout << "Error loading font " << fontName << std::endl; <- error: C2088: illegal for 
                                                                        class (where is there a class 
                                                                        involved?)
        exit(1);
    }

我基本上是在尝试从文件名后面的includes.h es.h头文件中加载一个字体,但是它会产生两个错误:(代码行中说明)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-06 10:08:24

我认为重新定义是因为缺少头球后卫!

今天,您可能会将该头包含在两个文件中,因此,现在代码被运行了两次,从而重新定义了所有的符号。

您还可以在所有头文件的开头使用#pragma once告诉链接器只包含该文件一次。

嗯,我对头文件中声明的全局变量没有多少经验,但我想我曾经有过这样一个奇怪的错误,我不得不在所有cpp文件中将全局变量转发到它的顶部。

代码语言:javascript
复制
extern fontName;

Wiki发布了关于头部警卫的帖子:

https://en.wikipedia.org/wiki/Include_guard

把我的答案加上去。从#开始的所有行实际上都是预处理器指令,这意味着它们的更改甚至在编译代码之前就发生了。

您可以想象,当您的代码有一个包含,所有的头实际上被粘贴到该文件与包含!

另外,#ifndef NAME的意思是,只有当预编译器不知道符号NAME时,该控件结构的主体才会运行。

如果是,那么#ifndef和#endif之间的所有内容都将被忽略。

注意我们做的第一件事是#define NAME,从而使预处理器知道符号存在,但为此,我们甚至不需要定义NAME的值,因为它与此无关。

这样,当下一次预处理程序找到#include "thatFile.h"时,它实际上不会复制任何代码。

有更多的这种控制结构。例如,我们可以使用#ifdef __unix__来包含只存在于Linux中的头,因此在不同的操作系统中编译时不会导致错误,并且允许更好的可移植性!

编辑:将链接更改为桌面和英文edit2:我的解释是错误的

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65166782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档