C++的多重定义.如何正确拆分C++程序

Multiple definition of C++. How to split C++ program properly?

本文关键字:C++ 何正确 拆分 程序 定义      更新时间:2023-10-16

我写了一个工作没有问题的程序,但我担心的是,当我用-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-lcrl-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自动生成的include保护程序——它们不应该很好吗?(创建新类时,它们会自动创建)

编辑:

您可以在这里下载带有错误日志的gedit文件:

http://www4.zippyshare.com/v/62324366/file.html

我不想在这里发布105行的错误,而且它是垃圾格式的,所以在这里看起来不太好。

服务器.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_ */

主要.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"

服务器.cpp

#include "Server.h"

排名创建者.cpp

#include "RankingCreator.h"

更改包含保护:

#ifndef FILENAME_H
#define FILENAME_H
//Code
#endif

我敢打赌你的问题已经过去了。显然,要确保每个FILENAME_H都是唯一的:)记住,每个标头都需要它的所有代码,但它不应该在源文件中。

用以下方式编写头文件:

#ifndef SERVER_H
#define SERVER_H
//...
#endif

它们被称为#include guards,以避免双重包含问题。在这里阅读他们

如果您在MVSC++上进行开发,您可以使用#pragma once作为每个标头的第一行,但第一个解决方案在每个平台上都是可移植的。