Связывание порядка и определения конструктора - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть следующие файлы:

ClassA.h:

#ifndef CLASS_A_H
#define CLASS_A_H

class A
{
public:
    A();
    double foo();
private:
    double value;
};

#endif

ClassA. cpp

#include "ClassA.h"

A::A()
{
    this->value = 1.0;
}

double A::foo()
{
    return this->value;
}

ClassB.h

#ifndef CLASS_B_H
#define CLASS_B_H

#include "ClassA.h"

class B
{
public:
    B();
    double bar();

private:
    A a;
};

#endif

Класс B. cpp

#include "ClassB.h"

B::B(){}

double B::bar()
{
    return this->a.foo();
}

main. cpp

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

int main()
{
    B b;
    std::cout << b.bar() << std::endl;
    return 0;
}

Если я собираю все вместе в исполняемый файл и запускаю (g++ *.cpp && ./a.out), я получаю ожидаемый результат.

Однако, если я скомпилирую два класса в разделяя библиотеки и пытаясь связать их в один исполняемый файл, я получаю ошибки связывания:

$ g++ -fPIC -c CLassA.cpp
$ g++ -fPIC -c CLassB.cpp
$ g++ -shared ClassA.o -o libClasssA.so
$ g++ -shared ClassB.o -o libClasssB.so
$ g++ main.cpp -L./ -lClassA -lClassB

$ .//libClassB.so: undefined reference to `A::A()'
$.//libClassB.so: undefined reference to `A::foo()'
$ collect2: error: ld returned 1 exit status

Один из способов исправить ошибку соединения - просто поменять местами порядок -lClassA и -lClassB в исполняемом файле. компиляция.

Однако я также обнаружил, что если я возьму конструктор B из файла. cpp и поместу его в заголовок, ошибка ссылки исчезнет.

Так что здесь мои два вопроса:

  1. Почему порядок ссылок здесь имеет значение? Эта запись StackOverflow утверждает, что порядок ссылок не имеет значения для динамических c libs.
  2. Почему перемещение реализации пустого конструктора B в файл. cpp вызывает ссылку ошибки?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...