错误C2011:' SelectorBox' :' class'类型重新定义

时间:2017-11-13 09:22:09

标签: c++ visual-studio-2013 compiler-errors

我遇到以下代码的问题:

 #ifndef HEADER_H_

    class SelectorBox{
    public:
        string selectorName;  
        map < string, string > attributeMap;
        void setSelectorName(string name);   
        void setAttribute(string key, string value); 
    };
    string trimTheString(string str); //trimming a string
    #endif

//include libraries 
#include "Header.h"
using namespace std;
int main()
{
    vector <SelectorBox> vectorSelectBox;
    SelectorBox *selectorBox;

//code
return 0;
}

#include "Header.h"
#include "main.cpp"

void SelectorBox::setSelectorName(string name)   //setter
{
    name = trimTheString(name);
    selectorName = name;
}

void SelectorBox::setAttribute(string key, string value)  //setter
{
    key = trimTheString(key);
    value = trimTheString(value);
    attributeMap[key] = value;
}

当我编译程序时,它显示许多错误(特别是错误4430和2061),但我认为主要错误是: 错误C2011:&#39; SelectorBox&#39; :&#39; class&#39;类型重新定义。

3 个答案:

答案 0 :(得分:1)

您要在main之后的main秒之前两次包含相同的标题,如果您不使用正确的包含警卫,则会导致问题。

您的include guard不完整,因此同一标头的多个包含将导致此错误。诀窍是检查是否定义了特定于头的预处理器名称:如果没有,则定义它,否则跳过整个头。

使用的模式是这样的

#ifndef GUARD
#define GUARD
/// the actual header contents
#endif

但只是将其复制到每个标题中会导致另一个问题,因为它缺少标题特异性。找到一个好名字的最简单方法是从文件名本身派生它。在你的情况下,我会在其中定义的类SelectorBox之后命名标题,因此SelectorBox.h将是一个好名字,并且包含警卫将如下所示:

#ifndef SELECTORBOX_H
#define SELECTORBOX_H

class SelectorBox {
/// etc.
};

#endif

使用具有相同包含保护的多个标头比使用不包含保护更糟糕。

答案 1 :(得分:1)

您必须定义HEADER_H_。你从下面的代码中错过了第二行。

#ifndef HEADER_H_
#define HEADER_H_
...
#endif

答案 2 :(得分:0)

我想,你有3个文件:

  • Header.h
  • main.cpp
  • FileX.cpp(到目前为止,你没有透露X先生的真实姓名)

main.cpp Header.h中,您FileX.cpp Header.h包括main.cppmain.cpp。让我展示一下这里发生的事情的简化版本:

//include libraries class SelectorBox{ public: string selectorName; map < string, string > attributeMap; void setSelectorName(string name); void setAttribute(string key, string value); }; string trimTheString(string str); //trimming a string using namespace std; int main() { vector <SelectorBox> vectorSelectBox; SelectorBox *selectorBox; //code return 0; } 的内容转化为

string

假设您包含了mapusing namespace std;,并且在您的类定义之前的某个地方还有另一个FileX.cpp,这可以编译而不会出错。

但现在让我们看看SelectorBox中会发生什么。其内容将转换为以下内容,我希望您现在可以看到编译器看到的内容:类class SelectorBox{ public: string selectorName; map < string, string > attributeMap; void setSelectorName(string name); void setAttribute(string key, string value); }; string trimTheString(string str); //trimming a string //include libraries class SelectorBox{ public: string selectorName; map < string, string > attributeMap; void setSelectorName(string name); void setAttribute(string key, string value); }; string trimTheString(string str); //trimming a string using namespace std; int main() { vector <SelectorBox> vectorSelectBox; SelectorBox *selectorBox; //code return 0; } void SelectorBox::setSelectorName(string name) //setter { name = trimTheString(name); selectorName = name; } void SelectorBox::setAttribute(string key, string value) //setter { key = trimTheString(key); value = trimTheString(value); attributeMap[key] = value; } 中有多个定义

{{1}}

...编译器用来称之为&#34;重新定义&#34;