【问题标题】:Linker Error: Duplicated Functions链接器错误:重复的函数
【发布时间】:2018-02-05 20:27:26
【问题描述】:

注意:我制作了一个 DFH_lib.CPP,其中包含 fstream 和 iomanip。我将所有模板函数保存在 DFH_lib.CPP 中。现在,如果我在 MAIN.CPP 中编写剩余的 NON-TEMPLATE 函数并仅包含 DFH_lib.h,那么它就会成功运行。我不明白为什么...

我正在使用模板制作一个数据文件处理库。我创建了两个文件:

DFH_lib.CPP
Lib_Test.CPP

我做了一个项目,点击编译下的“Build All”。我遇到了以下链接器错误:

在模块 DFH_LIB.CPP 中定义的file_init(char near*) 在模块 LIB_TEST.CPP 中重复

在模块 DFH_LIB.CPP 中定义的 AddColumn(const int near&) 在模块 LIB_TEST.CPP 中重复

file_init(char*);AddColumn(T data, const int& width);AddColumn(const int& width); 是我只在 DFH_lib.CPP 中定义的函数。我只在 Lib_Test.CPP 中调用了这些函数。

DFH_lib.CPP

template <class T>    //Function belongs to Pretty Printing Libary
void AddColumn(T data, const int& width) {
    cout<<setw(width)<<data<<" | ";
}
void AddColumn(const int& width) {
    cout<<setw(width)<<setfill('_')<<"|";
}
void file_init(char* file) {   //File initialization function
    ofstream fout;
    fout.open(file, ios::binary|ios::noreplace);   //File Created, noreplace prevents data loss
    fout.close();
}

Lib_Test.CPP

cout<<endl; AddColumn(record_id,7); AddColumn(char_member, 20); AddColumn(int_member, 11); AddColumn(float_member, 13);
file_init(file);    //initializes the file

其中“文件”定义为:char file[]="lib_Test.dat";

有人可以解释为什么我会收到此链接器错误吗?我不明白这是什么意思,因此,如何解决它......

编辑: 我注意到这可能是由于在包含文件时发生的错误导致的,因为我将 Lib_Test.CPP 变成了“Hello World”程序并出现了相同的错误。我还注意到一件事:只有非模板函数会导致链接错误!

DFH_lib.CPP

#ifndef _DFH_lib_cpp
#define _DFH_lib_cpp

#include<fstream.h>
#include<conio.h>
#include<stdio.h>
#include<iomanip.h>
#include<string.h>
.....
#endif

Lib_Test.CPP

#include<iostream.h>
#include<conio.h>
#include"DFH_lib.CPP"  //Including DFH Libary

【问题讨论】:

  • 您需要将#defines 添加到每个文件,同样也添加到lib_Test.cpp,问题也可能是模板的使用创建了一个已经存在的原型。 char_memberint_member 是如何定义的?如果它们相同,则可能是原因...包含层次结构看起来不错,因此它要么是模板中的错误,要么是其用法中的错误,没有完整的源代码我看不到...尝试执行MCVE(最小可编译可验证示例...在您的情况下不可编译:))
  • 给我时间,我这周有 3 门考试
  • 在您使用@spektre 进行编辑后通知我

标签: linker-errors turbo-c++


【解决方案1】:

我发现问题的原因如下:

  1. 编译器错误

    旧的 TC++ 有时会出现模板编译问题,通常会添加空行(在正确的位置)或交换一些代码帮助行。但这通常仅在您的源代码达到一定大小时才开始,例如 30-50 Kbyte 不再确定它在很久以前的价值。我不相信这是你的问题。

  2. 真的是重复的

    如果您多次包含某个文件,则会导致像您这样的错误。为了解决这个问题,您可以将每个文件封装成这样:

    #ifndef _DFH_lib_cpp
    #define _DFH_lib_cpp
    // here comes your file DFH_lib.cpp content
    #endif
    

    _DFH_lib_cpp 标记是您要封装的编码文件名。这将丢弃任何重复的包含。这也解决了存在全局变量的问题,但请注意,如果没有正确包含,它们在整个项目中可能不一样。

【讨论】:

  • 我认为它是集成的,我有构建所有、链接、制作、编译等选项。此外,DFH_lib.CPP 为 20KB,Lib_test.CPP 为 4KB。我会根据您的第二个建议做一些工作,如果问题仍然存在,我会回复您。
  • @AnkurSingh 是的,你是对的,刚刚在 DOS-BOX 中确认了它build all 也在那里,所以 #3 已经过时了。我会首先尝试 #2 每个文件只有 3 行代码.... 直到现在几十年都没有运行 bc.exe :)
  • 我确实在 DFH_lib.CPP 中添加了这些预处理器命令,但它没有帮助。我忘记包含的一件事是,我还将 DFH_lib.CPP 文件直接包含到 lib_Test.CPP 中。我没有使用导致 +7 错误的头文件。
  • @AnkurSingh 那些#ifndef/define/endif 应该在您获得的每个源文件中并封装所有内容(包括和常量在里面)。您的描述提示您错误的包含和程序结构层次结构。为了解决这个问题,我们需要看看你的包含是如何完成的……你项目的每个文件(不需要代码,只需要包含和全局 +/- 头文件)。只是为了确保看到How approximation search works 寻找_approx_h 每个文件都应该有唯一的#define 所以如果你使用文件名作为标记那么你就可以了。
  • @AnkurSingh 我敢打赌,你是在一次将更多的外国代码整合到单个项目中,而不是增量构建,这会直接告诉你问题出在哪里......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2012-06-13
  • 2014-08-11
  • 1970-01-01
相关资源
最近更新 更多