简单的C ++代码链接器错误

时间:2017-10-24 00:05:39

标签: c++ c++11 linker

我试图运行一个非常简单的代码片段。我一直在收到链接器错误。我的代码如下所示:

main.cpp - >

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

using namespace std;

int main()
{
   Complex c1(1.0, 5.0);  // this should create Complex object 1.0 + i5.0
   return 0;
}

Complex.h - &gt;

#include <iostream>

class Complex {
private:
    double real;
    double imaginary;

public:
    Complex(double, double);
    void setReal(double);
    void setImaginary(double);

};

Complex.cpp - &gt;

#include "Complex.h"
#include <cmath>

Complex::Complex(double x, double y) {
    setReal(x);
    setImaginary(y);
}
void Complex::setReal(double x) {
    real = x;
}
void Complex::setImaginary(double x) {
    imaginary = x;
}

我遇到的错误如下:Error photo

我一直试图运行我的main一段时间,但我不断收到链接器错误。我不知道导致它的原因。我很感激任何建议。

1 个答案:

答案 0 :(得分:2)

只做

g++ main-3.cpp complex.cpp

请注意文件名main-3,这在您的问题中是不一致的。 您必须将所有正在使用的cpp文件提供给g ++命令行,以告诉g ++标题中定义的函数的代码所在的位置。阅读.o文件,静态链接并了解其含义。

这是我遵循的一个小指南,用于理解文件包含和其他因素:

c ++编译很简单:

  1. 阅读.cpp文件
  2. 将每个#include语句替换为指定文件的文本(只是将其转储)
  3. 如果生成的文本仍然包含#include指令(现在来自头文件),请转到步骤2.
  4. 将hughe messy blob编译成'.o'目标文件,用符号替换函数调用,并在该文件中添加已知符号表及其定义位置。
  5. 如果指定了更多.cpp文件,则启动一个新的空文本blob。转到第1步。
  6. 调用链接器'ld'将所有目标文件链接在一起,用实际地址替换符号。
  7. 严格地说,现在上面有点谎言而且遗漏了很多,没有提到任何优化。但它仍然是编译器行为的有用指南。

    用它来解释你的错误: 通过Complex.h中的#includemain.cpp转储到您的blob中,但Complex.cpp没有。PUT 1.0 on Stack PUT 5.0 on Stack JUMP Complex::Complex 。 g ++为您生成了一个内部临时.o文件,其中包含

    Complex::Complex = 0xaaff
    

    ...并使用该.o文件运行链接器'old'。 ld找不到符号Complex :: Complex的地址, 它需要一个内存地址才能跳转到。 如果你也编译Complex.cpp,那么生成的Complex.o将有一个符号表,例如,这个条目:

    PUT 1.0 on Stack
    PUT 5.0 on Stack
    JUMP 0xaaff
    

    给定Complex.o的链接器现在可以用一个地址替换main.o中的符号。

        Future<Set<InternalPinResult>> oosSignal =
            pinsListFuture
                .flatMap(func((Pair<FeedSourceIdentifier, List<InternalPinResult>> pair) -> {
                  List<InternalPinResult> pinsCopy = pair.getSecond() != null
                                                     ? Lists.newArrayList(pair.getSecond())
                                                     : null;
                  return Future.value(pinsCopy.stream().filter((InternalPinResult pin) ->
                      pin != null
                          && blah).collect(Collectors.toSet()));
                }));
    
        System.out.println();
        // Activate the stock signal experiment only if user has atleast 1 out of stock pin.
        if (CollectionUtils.isEmpty(Future.value(oosSignal))) {
          # do something
        }