【问题标题】:error C2011: 'SelectorBox' : 'class' type redefinition错误 C2011:“选择框”:“类”类型重新定义
【发布时间】:2017-11-13 09:22:08
【问题描述】:

我对以下代码有疑问:

 #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: 'SelectorBox' : 'class' 类型重新定义。

【问题讨论】:

  • 请提供MCVE
  • 我们在谈论多少个文件
  • 你把#include "main.cpp"这行放在哪个文件里?
  • @Wolf OP 可能有多个文件但未显示 MCVE。
  • 明确哪些代码属于哪个文件,我的意思是:命名sn-ps!

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


【解决方案1】:

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

#ifndef HEADER_H_
#define HEADER_H_
...
#endif

【讨论】:

  • 试过了,没用。还尝试使用 #pragma 一次,但它对以太没有帮助。
【解决方案2】:

您包含两次相同的标头,第一次在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

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

【讨论】:

  • 试过了,没用。还尝试使用 #pragma 一次,但它对以太没有帮助。
  • @gusev 您包含两次相同的标题。
  • 下一个问题是你包含main.cpp,希望不在main.cpp 中;)
【解决方案3】:

我猜,你有 3 个文件:

  • Header.h
  • main.cpp
  • FileX.cpp(你至今没有透露X先生的真实姓名)

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

main.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;
}

假设您包含 stringmap 并且在您的类定义之前的某处还有另一个 using 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;
}

...编译器将其称为“重新定义”

【讨论】:

    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    相关资源
    最近更新 更多