编译器/链接器错误 "undefined reference"

6

你好,我刚开始学习C++。我买了一本《C++ for Dummies》的大书,一直在看。到目前为止,它非常有趣,但是现在我卡住了。我一直在谷歌这个问题,但是没有结果。我正在使用带有GNU GCC的Codeblocks 10.05。

我一直收到一个错误,上面写着:

In function 'main':
undefined reference to 'SafeCracker(int)'

这段代码并不复杂,只是我是新手,非常沮丧。我不想跳过这部分,我想知道发生了什么。

主要:

#include <iostream>
#include "safestuff.h"

using namespace std;

int main()
{
  cout << "Surprise, surprise!" << endl;
  cout << "The combination is (once again)" << endl;
  cout << SafeCracker(12) << endl;
  return 0;
}

功能:

#include <iostream>

using namespace std;

string SafeCracker(int SafeID)
{
    return "13-26-16";
}

标题:

using namespace std;

#ifndef SAFESTUFF_H_INCLUDED
#define SAFESTUFF_H_INCLUDED

 string SafeCracker(int SafeID);

#endif // SAFESTUFF_H_INCLUDED

你不知道你缺少什么?你不是太空总统,这是一件事。你也没有把所有的文件链接在一起。 - Kerrek SB
2
展示一下你是如何构建它的 - 链接阶段出了问题。 - Carl Norum
1
那个错误信息意味着编译器无法找到 SafeCracker 的定义(即函数实际的代码)。您是否已将包含该函数的文件添加到您的代码块项目中? - David Brown
这是代码块项目的一部分。我不太清楚它是如何构建的,因为代码块已经处理了那部分。在编译器设置中需要做些什么吗? - Tetrah
顺便提一下,您正在使用字符串数据类型,但未包含字符串类。您应该将“#include <string>”(不带引号)放在“#include <iostream>”上方或下方。一些编译器会自动为您包含头文件,当它们检测到缺少一个时,但这不是标准,因此不应依赖它。 - Logan Besecker
2个回答

2

你没有同时编译你列出的第二个文件。尝试使用gcc直接进行编译以了解原因。

假设你的文件名为:

  • main.cpp
  • SafeCracker.cpp
  • safestuff.h

这是你正在做的事情

gcc main.cpp

而你应该这样做

gcc main.cpp SafeCracker.cpp

此外,为了清晰起见,SafeCracker.cpp也应包括头文件。你将它们分开的原因是什么呢?

另外,从看到Daniel Hu的答案,<iostream>会自动为你包含<string>。你不应该依赖这种功能,而应该在每个使用字符串的文件中包含<string>

(来自下面的评论) 你可能正在尝试将main.cpp作为一个独立的文件构建。这将导致SafeCracker.cpp未编译。你需要在Codeblocks中创建一个项目,并将所有三个文件都添加到其中(*.cpp文件以及*.h文件)。


没有什么好的理由让我老实地跟随我所看到的。我不太确定如何直接编译,我得去研究一下。 - Tetrah
我正在使用64位家庭高级版的Windows 7操作系统。 - Tetrah
1
你可能正在尝试将main.cpp作为独立文件进行构建。这将导致SafeCracker.cpp未编译。你需要在Codeblocks中创建一个项目,并将所有三个文件添加到其中(包括*.cpp文件和*.h文件)。 - Nikos C.
@Tetrah,我发现最简单的方法是创建一个项目,然后只需创建文件并在询问是否要将它们添加到项目时选择“是”。如果没有项目,您将不得不在实现中包含头文件并在主文件中包含实现,将实现包含在头文件底部并在主文件中包含头文件,或在实现文件中包含头文件,同时在主文件中包含两者,并确保头文件具有头文件保护。当然,您也可以在IDE之外编译它。 - chris
@Tetrah - 既然“那样做就可以了”,接受这个答案。这就是我们这里的做事方式。 - David Hammen
显示剩余2条评论

1

我认为这是因为你没有 #include <string>

C++必须导入字符串库才能使用字符串,否则所有内容都将被视为字符数组。


@jett -- 永远不要依赖那个。#include你使用的内容。此外,SafeCracker.cpp 不应该包含 iostream,因为该文件没有使用 iostream。不要 #include 你不使用的内容。该文件正在定义函数 SafeCracker。该函数在某个头文件中声明为返回 std::string。不是指针,也不是引用。只是 std::string。这就是 #include <string> 所属的头文件。 - David Hammen
@DavidHammen 我同意您应该包含您使用的内容,我在上面的答案中提到了这一点。我只是想说这不是解决问题的方法。 - jett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接