我正在使用此头文件来读取文本文件(我用它来加载着色器文件),我在两个不同的类中使用它。
我收到错误textFileRead(char *)的多重定义。
这是头文件:
#ifndef READFILE_H
#define READFILE_H
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "string"
#include "fstream"
char *textFileRead(char *fn) {
FILE *fp;
char *content = NULL;
int count=0;
if (fn != NULL) {
fp = fopen(fn,"rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
#endif READFILE_H
我做错了什么?
答案 0 :(得分:0)
您需要确保头文件中的代码仅包含在每个编译单元中一次。为此,您将其放在文件的开头:
#ifndef READFILE_H
#define READFILE_H
最后:
#endif
当然,标识符READFILE_H对于每个文件应该是唯一的。接下来要做的是:只在头中保留函数和类的声明,实现应该存在于单独的实现文件(.c或.cpp或.cc)中。因此,在您的标题中,您将仅声明您的函数:
char *textFileRead(char *);
,你的函数定义将在一个单独的.c文件中。
答案 1 :(得分:0)
标题中定义的函数需要标记为inline
以防止多重定义。
这个,或者将实现分离到实现文件。
在同一翻译单元中包含防范多重定义的警卫,这是一个链接器问题。该符号在翻译单元中定义了多次。
答案 2 :(得分:0)
您正在头文件中定义该函数,这意味着编译器将在包含此标头的每个源文件中复制相同的函数。在链接目标文件时,链接器将不知道要使用哪个版本。 (它不能知道它们是相同的,只是它们的签名是相同的。)
解决此问题的一种方法是将实现移动到源文件,并将声明保留在头文件中,如下所示:
<强> readfile.h 强>
#ifndef READFILE_H
#define READFILE_H
char *textFileRead(char *fn);
#endif
<强> readfile.cpp 强>
#include "readfile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>
char *textFileRead(char *fn)
{
FILE *fp;
char *content = NULL;
int count=0;
/* ... code ... */
return content;
}
另一种解决方案是标记函数inline
并将实现保留在头文件中。像这样:
#ifndef READFILE_H
#define READFILE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>
inline char *textFileRead(char *fn)
{
FILE *fp;
char *content = NULL;
/* ... code ... */
return content;
}
在最后一种情况下,编译器可以选择内联调用它的函数,而不是生成对它的调用。
在上面的示例中,也可以使用static
代替inline
,或者在匿名命名空间中包含定义。但是,建议不要使用这些方法。除非您有特定的理由想要在函数头文件中内联函数并使其正文可用,否则我会选择第一种方法。