C++ 的多重定义。如何拆分 C++程序正确吗?
我编写了一个可以正常运行的程序,但我担心的是,当我使用 -Wall 选项编译它时(它是用 C 和 C++ 编写的程序),我会收到很多警告。实际上只有一种类型的警告,但出现多次:多重定义....(构造函数、析构函数和函数)。我以为我做得对,但显然我错了。我有9个文件:
Server.h
Server.cpp - implements methods declared in Server.h
RankingCreator.h
RankingCreator.cpp - implements methods declared in RankingCreator.h
Parser.h
Parser.cpp - implements methods declared in Parser.h
PageHandler.h
PageHandler.cpp - implements methods declared in PageHandler.h
并且
Main.cpp
-所有头文件都包含在这个文件中,因为我使用并组合 这里所有类的功能
除Main.cpp之外的每个.cpp文件仅包含一个相应的.h文件,例如Server.cpp包含#include“server.h”并且上面没有列出更多.h / .cpp文件(但它确实包含诸如 stdio.h 和 string.h 之类的标头)。我可以在这里发布整个警告消息和类的代码,但错误的长度约为 50 行,所有类将约为 1000 行,所以请告诉我是否真的需要解决这个问题。知道如何解决这个问题吗?我是否必须使每个函数都内联或者什么?每个头文件开头都有#if def 块。
编辑: 这是警告日志:
g++ LearnTidyCurl.cpp MyParser.cpp PageHandler.cpp RankingCreator.cpp Server.cpp -lcurl -ltidy -o -Wall Wynik
这是我的头文件之一的代码,请参阅 ifdefs 的方式:
#ifndef RANKINGCREATOR_H_
#define RANKINGCREATOR_H_
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
//using namespace std;
struct rankingElement {
std::string url;
int rank;
bool operator() (rankingElement i, rankingElement j) { return (i.rank > j.rank);}
} ;
bool operator==(const rankingElement& elem, const std::string& url);
class RankingCreator {
public:
rankingElement compareRankingElements;
const static int MAX_QUERY_RESULT_SIZE = 20;
RankingCreator();
virtual ~RankingCreator();
bool checkPageRank( rankingElement rElement, std::vector<rankingElement> &ranking );
void insertIntoRanking( rankingElement rElement, std::vector<rankingElement>& ranking);
};
#endif /* RANKINGCREATOR_H_ */
我抛出警告消息出去,因为它使这个主题不可读。 顺便提一句。我使用 Eclipse 自动生成的包含防护 - 它们不应该很好吗? (创建新类时,它们会自动创建)
编辑:
您可以在此处下载带有错误日志的 gedit 文件:
http://www4.zippyshare.com/v/62324366/file.html
我不想在这里发布 105 行错误,而且它是垃圾格式,所以这里不好看。
Server.h :
#ifndef SERVER_H_
#define SERVER_H_
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <vector>
...body...
#endif /* SERVER_H_ */
PageHandler.h
#ifndef PAGEHANDLER_H_
#define PAGEHANDLER_H_
#include <tidy.h>
#include <buffio.h>
#include <stdio.h>
#include <errno.h>
#include <iostream>
#include <string.h>
#include <curl/curl.h>
#include <vector>
#include <algorithm>
#include <stdexcept>
... body ...
#endif /* PAGEHANDLER_H_ */
MyParser.h
#ifndef MYPARSER_H_
#define MYPARSER_H_
#include <vector>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <algorithm>
#include <queue>
#include <stdlib.h>
...body...
#endif /* MYPARSER_H_ */
Main.cpp
#include <stdio.h>
#include <iostream>
#include <queue>
#include "MyParser.h"
#include "PageHandler.h"
#include "RankingCreator.h"
#include "Server.h"
#define NO_ERROR 0
std::string convertIntToString(int input) {
std::ostringstream ss;
ss << input;
std::string tmpStr = ss.str();
return tmpStr;
}
int main(int argc, char **argv) {
... body ...
return 0;
}
MyParser.cpp
#include "MyParser.h"
PageHandler.cpp
#include "PageHandler.h"
Server.cpp
#include "Server.h"
RankingCreator.cpp
#include "RankingCreator.h"
I wrote a program that works without problems, but the thing I am afraid of is that I get a lot of warnings, when I compile it with -Wall option ( it's program written in C and C++). Actually there is only one type of warning, but occurs many times : Multiple definition of .... ( contructors , destructors, and functions ). I thought I did it correcly, but obviously I am wrong. I have 9 files:
Server.h
Server.cpp - implements methods declared in Server.h
RankingCreator.h
RankingCreator.cpp - implements methods declared in RankingCreator.h
Parser.h
Parser.cpp - implements methods declared in Parser.h
PageHandler.h
PageHandler.cpp - implements methods declared in PageHandler.h
and
Main.cpp
- all header files are included in this file, because I use and combine
functionality of all classes here
Each .cpp file except Main.cpp contains only one corresponding .h file included, for instance Server.cpp contains #include "server.h" and no more .h/.cpp files listed above ( but it does contain headers like stdio.h and string.h ). I can post whole warning message here and code of classes, but the lenght of error is about 50 lines, and all classes would be about 1000 lines, so tell me if it is really needed to solve this. Any idea how to solve this? Do I have to make every function inline or something? Every header file has #if def block at the beginning.
EDIT:
Here is the warning log :
g++ LearnTidyCurl.cpp MyParser.cpp PageHandler.cpp RankingCreator.cpp Server.cpp -lcurl -ltidy -o -Wall Wynik
Here is code of one of my header files, see the way of ifdefs :
#ifndef RANKINGCREATOR_H_
#define RANKINGCREATOR_H_
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
//using namespace std;
struct rankingElement {
std::string url;
int rank;
bool operator() (rankingElement i, rankingElement j) { return (i.rank > j.rank);}
} ;
bool operator==(const rankingElement& elem, const std::string& url);
class RankingCreator {
public:
rankingElement compareRankingElements;
const static int MAX_QUERY_RESULT_SIZE = 20;
RankingCreator();
virtual ~RankingCreator();
bool checkPageRank( rankingElement rElement, std::vector<rankingElement> &ranking );
void insertIntoRanking( rankingElement rElement, std::vector<rankingElement>& ranking);
};
#endif /* RANKINGCREATOR_H_ */
I threw warning message out, because it makes this topic unreadable.
Btw. I use include guards auto-generated by Eclipse - shouldn't they be just fine? ( When creating a new class they are automatically created )
EDIT:
You can download gedit file with error log here :
http://www4.zippyshare.com/v/62324366/file.html
I didn't want to post 105-lined error here and in addition it is in crap format, so would not good look here.
Server.h :
#ifndef SERVER_H_
#define SERVER_H_
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <vector>
...body...
#endif /* SERVER_H_ */
PageHandler.h
#ifndef PAGEHANDLER_H_
#define PAGEHANDLER_H_
#include <tidy.h>
#include <buffio.h>
#include <stdio.h>
#include <errno.h>
#include <iostream>
#include <string.h>
#include <curl/curl.h>
#include <vector>
#include <algorithm>
#include <stdexcept>
... body ...
#endif /* PAGEHANDLER_H_ */
MyParser.h
#ifndef MYPARSER_H_
#define MYPARSER_H_
#include <vector>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <algorithm>
#include <queue>
#include <stdlib.h>
...body...
#endif /* MYPARSER_H_ */
Main.cpp
#include <stdio.h>
#include <iostream>
#include <queue>
#include "MyParser.h"
#include "PageHandler.h"
#include "RankingCreator.h"
#include "Server.h"
#define NO_ERROR 0
std::string convertIntToString(int input) {
std::ostringstream ss;
ss << input;
std::string tmpStr = ss.str();
return tmpStr;
}
int main(int argc, char **argv) {
... body ...
return 0;
}
MyParser.cpp
#include "MyParser.h"
PageHandler.cpp
#include "PageHandler.h"
Server.cpp
#include "Server.h"
RankingCreator.cpp
#include "RankingCreator.h"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
改变你的包容守卫:
我敢打赌你的问题就会消失。显然,请确保每个 FILENAME_H 都是唯一的:)并记住 - 每个标头都需要它的所有代码,但它不应该出现在您的源文件中。
Change your inclusion guards:
And I bet your problem goes away. Obviously make sure each FILENAME_H is unique :) And remember - each header needs this around all it's code, but it shouldn't be in your source files.
按以下方式编写头文件:
它们被称为
#includeguards
以避免双重包含问题。在此处阅读有关它们的信息。如果您曾经在 MVSC++ 上进行开发,则可以使用
#pragma 一次
作为每个标头的第一行,但第一个解决方案在每个平台上都是可移植的。Write your header files the following way:
They are called
#include guards
to avoid double inclusion problems. Read about them hereIf you are ever developing on MVSC++, you can use
#pragma once
as a first line of each header, but the first solution is portable on every platform.