Ошибка C lld-link при доступе к классу A через указатель из класса A_test

#c #linker

#c #компоновщик

Вопрос:

Теперь у нас есть класс A, в заголовочном файле которого определена структура C.

Конструктор копирования класса A и оператор присваивания копирования должны быть удалены, поскольку один из его членов класса имеет удаленный конструктор копирования и удаленный оператор присваивания копирования.

Затем у нас есть класс ATest, у которого есть указатель на экземпляр класса A, и мы используем этот указатель для выполнения ряда задач проверки. Код приведен ниже:

A.h

 public:
  A();
  A(const Aamp;) = delete;
  Aamp; operator=(const Aamp;) = delete;
  ~A() override;


  struct C{
     public:
      C(int id);
      C(const Camp; other);
      ~C();
      int id;
  };

  const std::vector<C>amp; GetC() const;

 Private:
  std::vector<C> c_;
  

A.cc

 A::A() {
  // skip the implementation detail here
}
A::~A() = default;

const std::vector<A::C>amp; A::GetC() const {
  return c_;
}

A::C::C(int input_id)
    : id(input_id) {}
A::C::~C() = default;
A::C::C(const Camp; other) = default;
  

A_test.cc

 #include "A.h"

// Test class definition and implementation.
class ATest {
 public:
  ATest() = default;
  ~ATest() = default;

  void SetUpTestEnv() {
    auto a = std::make_unique<A>();
    a_ = a.get();
  }

 private:
  A* a_;
}

// In test execution code:
SetUpTestEnv();
a_->GetC().size()    // lld-link: error: undefined symbol: public: class std::__1::vector<struct A::C, class std::__1::allocator<struct A::C>> const amp; __cdecl A::GetC(void) const
  

В целом мы видим ошибку связывания следующим образом:

 lld-link: error: undefined symbol: public: class std::__1::vector<struct A::C, class std::__1::allocator<struct A::C>> const amp; __cdecl A::GetC(void) const
lld-link: error: undefined symbol: public: __cdecl A::A(void)
lld-link: error: undefined symbol: public: virtual __cdecl A::~A(void)
  

Я совсем запутался, в чем причина этой ошибки связывания? A.h и A.cc уже добавлен в качестве зависимости для A_test.cc во время компиляции. Я действительно ценю ваши предложения и советы! Спасибо!

Комментарии:

1. Вам нужен объект ATest для доступа к_

2. Покажите нам вашу систему сборки для компиляции A_test.cc в реальную работоспособную программу.

3. К вашему сведению, a_ = a.get(); — как вы думаете a_ , что указывает на то, что один раз a уничтожается при выходе из функции SetUpTestEnv ? Объект a , на который указано, исчез , поскольку интеллектуальный указатель, которому он принадлежал, уничтожен. При этом a_ теперь содержит висячий указатель, и любое его разыменование вызывает неопределенное поведение .

4. @WhozCraig на самом деле мы передаем право собственности на a другому объекту с помощью std::make_unique<B>(nullptr, std::move(a), std::move(thread_b));

5. @Botje спасибо за ваши комментарии, проблема действительно заключается в BUILD.gn файл, первоначально A.cc и А.х. был связан с A_test.cc однако, как deps, по какой-то причине это не работало. Теперь с конкретным добавлением A.cc чтобы A_test.cc как источник, он способен успешно строить. Все еще было странно добавлять A.cc как депс это не сработает.