错误 C2011 'vars::strct': 'struct' 类型重定义

Error C2011 'vars::strct': 'struct' type redefinition

本文关键字:类型 定义 struct vars C2011 错误 strct      更新时间:2023-10-16

vars.cpp

#pragma once
#include "vars.h"
namespace vars
{
struct strct
{
bool enabled = false;
};
}

vars.h

#pragma once
namespace vars
{
extern struct strct
{
bool enabled = false;
};
}
extern vars::strct *variables = new vars::strct[ 6 ];

我越来越'vars::strct': 'struct' type redefinition in vars.cpp

问题出在哪里?

您已经定义了两次结构,这与一个定义规则冲突,因此错误。如果在vars.cpp中包含vars.h文件,则会在vars.cpp文件中定义该结构。

注意

vars.h文件中不需要extern关键字,因为您定义的是结构体,而不是要全局使用的构造体实例。有关详细信息,请参阅何时在 C++ 中使用 extern。

此外,您在.cpp文件中使用了#pragma once。在大多数情况下,您不包括.cpp文件,因此它是多余的。

这里有几件事出了问题。

extern是一个存储类说明符,用作编译器的承诺,即变量存在,即使它尚未找到它的定义。可以安全地使用该变量,链接器将负责跟踪稍后定义它的位置。

无需将类型定义为extern,并且可能会收到告知您的诊断。

所以修复1:从类型中删除extern

#pragma once
namespace vars
{
struct strct
{
bool enabled = false;
};
}
extern vars::strct *variables = new vars::strct[ 6 ];

现在,当 vars.cpp 被编译时,vars.h 将被包含,将 vars.cpp 转换为

#pragma once
namespace vars
{
extern struct strct
{
bool enabled = false;
};
}
extern vars::strct *variables = new vars::strct[ 6 ];
namespace vars
{
struct strct
{
bool enabled = false;
};
}

很明显,strct被定义了两次。Vars.cpp不需要它自己的定义。删除它。

vars.cpp需要的是兑现variables存在某个地方的承诺,将我们带到问题2。

extern vars::strct *variables = new vars::strct[ 6 ];

extern变量是变量存在的承诺。目前还没有variables,所以初始化它是不确定的。编译器似乎允许它,但编译器允许很多人类的愚蠢行为。

通常,您不希望标头中的变量定义,因为包含标头的所有文件都会获得标头的副本。#pragma once将合理地确定(据我所知,仍然有一些失败的情况(每个翻译单元的标题只包含一次。但是每个翻译单元都有自己的定义,您马上就可以整理多个定义错误。

修复2:你真正想要的是

瓦尔斯·

#pragma once
namespace vars
{
struct strct
{
bool enabled = false;
};
}
extern vars::strct *variables; // variables exists somewhere

和变量.cpp

#include "vars.h"
vars::strct *variables = new vars::strct[ 6 ]; // variables exists here

现在只有一个变量,任何#include "vars.h"的人都可以使用它,假设他们编译并链接 vars.cpp。

请注意,#pragma once已从 vars.cpp 中删除。这是不必要的。如果您发现自己包含 cpp 文件,那么您已经在某个地方迷路了。别这样。