C++ 错误C2011:&x27;成员';:';结构';将结构移动到新头文件时的类型重新定义
我有一个带有一些类代码的.h文件-overlay.hC++ 错误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
#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