textFileRead(char*)的多重定义
Multiple Definition of 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] = ' ';
}
fclose(fp);
}
}
return content;
}
#endif READFILE_H
我做错了什么?
表头定义的函数需要标记为inline
,以防止多重定义。
要么这样,要么将实现分离到一个实现文件中。
在同一翻译单元中包含防止多个定义的保护,这是一个链接器问题。符号在翻译单位中定义多次。
您需要确保头文件中的代码只为每个编译单元包含一次。要做到这一点,您可以将其放在文件的开头:
#ifndef READFILE_H
#define READFILE_H
最后这个:
#endif
当然,标识符READFILE_H对于每个文件都应该是唯一的。接下来要做的是:在头中只保留函数和类的声明,实现应该存在于一个单独的实现文件(.c或.cpp或.cc)中
char *textFileRead(char *);
函数的定义将在一个单独的.c文件中。
您在头文件中定义函数,这意味着编译器将在包含此头的每个源文件中复制相同的函数。当链接对象文件时,链接器将不知道要使用哪个版本。(它不能知道他们是一样的,只是他们的签名是一样的。)
解决此问题的一种方法是将实现移动到源文件,并将声明保留在头文件中,如下所示:
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
,或者将定义包围在匿名命名空间中。然而,这两种方法都不推荐使用。除非您有特定的原因想要潜在地内联您的函数并使其正文在头文件中可用,否则我会选择第一种选择。
相关文章:
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- 为什么从 char 转换为 std::byte 可能是未定义的行为?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 将结构 std::memcpy 转换为具有足够容量的 std::vector 是未定义的行为<char>吗?
- 包括"lvtocon.h",未定义对'operator<<(std::ostream&, char const*)的引用
- 未定义模板"std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator&
- C++ 如何检查 char 变量是否未定义(未初始化)
- 将字符串文本常量定义为 char const* 和 wchar const*
- 定义.cpp中常数int/char*
- 仅使用 bool 和 char 定义一个 templete 类
- 是否很好地定义了强制转换为仅由 char[] 组成的结构并从该数组读取?
- 来自 cpp首选项的用户定义的 const char* 文字示例
- gtest - 未定义对"testing::InitGoogleTest(int*, char**)"的引用
- Qt5 对'QApplication::QApplication(int&, char**, int)'的未定义引用
- 自定义char*插入功能多次运行时会产生运行时错误
- 如何在 C++ 中安全地为 char *array 重新分配内存(它适用于自定义字符串类)
- [lex.ccon] 中 c-char 的定义可能存在矛盾
- 定义char数据类型,并与sprintf一起使用
- 定义 char 和 int 时指针有什么区别