У меня есть следующие файлы:
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 и поместу его в заголовок, ошибка ссылки исчезнет.
Так что здесь мои два вопроса:
- Почему порядок ссылок здесь имеет значение? Эта запись StackOverflow утверждает, что порядок ссылок не имеет значения для динамических c libs.
- Почему перемещение реализации пустого конструктора
B
в файл. cpp вызывает ссылку ошибки?