使用类进行链接时发生简单的C++未定义引用错误

Simple C++ undefined reference error during linking while using a class

本文关键字:简单 C++ 未定义 错误 引用 链接      更新时间:2023-10-16

我有一个简单的问题。但由于我是C++编程的新手,我无法解决这个问题。我创建了一个新的C++项目,使代码尽可能简短(因为原始代码要长得多),同时保留我遇到的问题。我在Stackoverflow和谷歌上搜索了大约50个相关问题,但到目前为止,没有任何东西能帮助我解决它。把所有东西都放在一个cc和一个h文件中是有效的,但不是我喜欢做的。提前感谢您的帮助。

我使用的是Ubuntu 14.04/Code::Blocks 13.12/gcc和g++4.8.2

问题是,我想访问在不同文件中定义的类中的函数,并且在编译工作时(由于file1.h中的extern)链接失败。如果我只是在file1.h中放入"Simple S1;"而不是"extern Simple S1!",并将其从file1.cc中删除,我会得到一个预期的多重声明错误。显然,"extern"技巧不适用于类,而适用于变量。

file1.h:

#ifndef FILE1_H
#define FILE1_H
class Simple
{
    private:
    unsigned int length = 10;
    public:
    void SetLength(unsigned int l) {length = l;}
    unsigned int GetLength() {return length;}
};
extern Simple S1;
#endif

file1.cc:

#include <iostream>
#include "file1.h"
#include "file2.h"
int main()
{
    Simple S1;
    unsigned int l = GetL();
    std::cout << "length=" << l << "n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "n";
    return 0;
}

file2.h:

#ifndef FILE2_H
#define FILE2_H
unsigned int GetL();
#endif

file2.cc:

#include "file1.h"
#include "file2.h"
unsigned int GetL()
{
    return S1.GetLength();
}

构建命令和错误:

g++ -std=c++11 -Wall -fexceptions -g  -c file1.cc -o obj/Debug/file1.o
g++ -std=c++11 -Wall -fexceptions -g  -c file2.cc -o obj/Debug/file2.o
g++  -o bin/Debug/Test obj/Debug/file1.o obj/Debug/file2.o   
obj/Debug/file2.o: In function `GetL()':
file2.cc:6: undefined reference to `S1'
collect2: error: ld returned 1 exit status

如果S1是全局的,它必须在全局范围内定义,而不是在main()内定义,main()会创建该函数的本地新实例。

在函数中,将Simple S1;放在main()之前。

#include <iostream>
#include "file1.h"
#include "file2.h"
Simple S1;
int main()
{
    unsigned int l = GetL();
    std::cout << "length=" << l << "n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "n";
    return 0;
}
extern Simple S1;

该声明承诺在代码中的其他地方有一个类型为Simple的全局对象S1。但你从来没有定义过这样一个对象。最接近的是main()中的局部变量S1,但当然,这是完全不同的。

因此,只需将S1的定义移出main():

Simple S1;
int main()
{
    unsigned int l = GetL();
    std::cout << "length=" << l << "n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "n";
    return 0;
}