C++ 错误C2011:&x27;成员';:';结构';将结构移动到新头文件时的类型重新定义

C++ 错误C2011:&x27;成员';:';结构';将结构移动到新头文件时的类型重新定义,c++,boost,C++,Boost,我有一个带有一些类代码的.h文件-overlay.h #include<iostream> #include<boost/thread.hpp> #include<vector> #include<boost/asio.hpp> #include <string> #include <boost/serialization/vector.hpp> #include

我有一个带有一些类代码的.h文件-overlay.h

    #include<iostream>
    #include<boost/thread.hpp> 
    #include<vector>
    #include<boost/asio.hpp> 
    #include <string>
    #include <boost/serialization/vector.hpp>
    #include <boost/archive/text_oarchive.hpp> 
    #include <boost/archive/text_iarchive.hpp> 
    #include <sstream> 
    #include <boost/tuple/tuple.hpp>
    #include<member.h>
    using boost::asio::ip::tcp;

    class overlay_server{...};

struct member{
    std::string ip_address;
    short int port;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & ip_address;
        ar & port;
    }
};
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用boost::asio::ip::tcp;
类覆盖服务器{…};
结构成员{
std::字符串ip_地址;
短int端口;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&ip_地址;
ar&port;
}
};
现在我将结构移到另一个名为member.h的新文件中 并包含此文件,以便我的类覆盖服务器可以使用它。 现在,当我构建程序时,我得到了错误

我应该做什么样的改变才能使它工作? 我在SO上读到了标题保护,但我真的不知道如何在这里实现它来解决问题

----编辑----

成员:h

struct member{
    std::string ip_address;
    short int port;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & ip_address;
        ar & port;
    }
};
struct成员{
std::字符串ip_地址;
短int端口;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&ip_地址;
ar&port;
}
};
run.cpp

    #include<overlay_server.h>
#include<overlay_client.h>

int main(){

    overlay_server overlay_server_(8002);
    boost::thread thread_(boost::bind(&overlay_server::member_list_server, overlay_server_));


    overlay_client overlay_client_("127.0.0.1",8002);
    overlay_client_.member_list_client();

    thread_.join();
}
#包括
#包括
int main(){
覆盖服务器覆盖服务器(8002);
boost::thread线程(boost::bind(&overlay\u server::member\u list\u server,overlay\u server));
覆盖客户覆盖客户(“127.0.0.1”,8002);
覆盖_client_.member_list_client();
螺纹连接();
}
我在任何地方都没有对struct的重新定义。 我有另一个名为overlay_client的类,它也使用struct member

在我的主要功能中,我创建了overlay_服务器和overlay_客户端的对象。 现在,我的程序只有在overlay_server.h中包含member.h时才运行(尽管overlay_server和overlay_client中的代码都需要它) 如果它包含在两者中,那么我会得到重新定义错误

为什么?

----编辑----

我的member.h中的这段代码解决了这个问题
如果
overlay.h
包含
struct成员
定义和
member.h
也包含
struct成员
定义,则不能从
overlay.h
中包含
member.h
。以下是include guards的工作原理:

        #include<iostream>
        #include<boost/thread.hpp> 
        #include<vector>
        #include<boost/asio.hpp> 
        #include <string>
        #include <boost/serialization/vector.hpp>
        #include <boost/archive/text_oarchive.hpp> 
        #include <boost/archive/text_iarchive.hpp> 
        #include <sstream> 
        #include <boost/tuple/tuple.hpp>
        #include<member.h>
   #ifndef _H__MEMBER_
   #define _H__MEMBER_
        using boost::asio::ip::tcp;
        class overlay_server{...};

    struct member{
        std::string ip_address;
        short int port;

        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & ip_address;
            ar & port;
        }
    };
#endif
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#ifndef成员_
#定义\u H\u成员_
使用boost::asio::ip::tcp;
类覆盖服务器{…};
结构成员{
std::字符串ip_地址;
短int端口;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&ip_地址;
ar&port;
}
};
#恩迪夫

请注意
\ifndef\u H\u成员
\define\u H\u成员
\endif
。使用includeguard,它可以确保您的头只包含一次,因为在第一次包含它之后,H_MEMBER_uu将已经定义,因此它将跳过定义。您的命名约定可能会有所不同,但通常我会按照自己定义的
\u H\uuuu
来做一些事情

您也可以使用
pragma
获得相同的效果。在所有头文件的顶部,写下:

#pragma once

rest of the header
 .
 .
 .
使用include-guard的方法是用include-guard包围头文件中的所有内容,如下所示:

// At the very top
#if !defined(SOME_SYMBOL)
#define SOME_SYMBOL

rest of the header
 .
 .
 .

// At the very bottom
#endif  // SOME_SYMBOL
现在,选择一个合理的名称而不是某个符号是非常重要的。大多数程序员根据文件名(以及路径和项目名以及公司/个人名)来命名保护名称。例如,对于位于“[project root]/include/myproject”中的名为“some_header.h”(或“SomeHeader.h”)的头,您可以将保护名称命名为
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但这只是一个建议;任何独特的符号都可以

您还可以将
pragma
和include-guard组合使用(因为
pragma
方法可以在非常大的项目中提高编译时间,但并非所有编译器都支持它)。如果您希望两者都使用,您可以编写:

#pragma once

#if !defined(__INCLUDE__MY_PROJECT__SOME_HEADER_H__)
#define __INCLUDE__MY_PROJECT__SOME_HEADER_H__

rest of the header
 .
 .
 .

#endif  // __INCLUDE__MY_PROJECT__SOME_HEADER_H__
据我所知,这没有任何负面影响,只是有可能防止生成错误并加快生成速度(在大型项目上)。但请注意,include guard和
#pragma once
的含义并不完全相同。在非常罕见的情况下,您需要使用其中一种,或者两者都不使用。

这就是发生的情况。 你有

member.h

包含在
overlay\u server.h
overlay\u client.h

现在,当您在main.cpp中包含这两个

这就像您在main.cpp中执行此操作一样(实际上预处理器如下所示展开)

因此,在完全扩展之后,通常会是这样

struct member{...};
struct member{...};    //redifinition!!
因此编译器将其解析为
结构成员的两个定义(因为它将访问member.h两次并读取member struct的定义)

如何避免这种情况

在member.h中添加以下内容

#ifndef MEMBER_DECL    //initially not defined
#define MEMBER_DECL    //include guard(now first time you enter this MEMBER_DECL will get defined. so second time compiler comes here it skips this.)
struct member
{
 //rest here
};

#endif
现在基本上你会有这个

#include"member.h" //when this happens MEMBER_DECL is defined
所以


在重新构建解决方案之前,您是否清理了它?您遇到了什么错误?可能是标题中的错误。您是否弄乱了include guards或有多个定义?顺便问一下,您在哪里定义了类?而且您正在使用
我认为您最好使用
作为自定义标题。我还没有为您的“为什么?”,编写任何include-guards。由于两次包含同一定义,因此会出现重新定义错误。收割台防护装置防止这种情况发生。有时你也可以把结构成员;例如,在overlay_client.h中,然后#包括在overlay_client中。cpp@Brad为什么要在
#include
语句之后放置include防护?有什么原因吗?据我所知,这只会使构建速度变慢,因为编译器可能必须打开这些构建
#include"member.h" //when this happens MEMBER_DECL is defined
//#include"member.h" member will not be expanded again hence resolving your redfinition