Встраивание методов класса C ++ приводит к неопределенной ссылке - PullRequest
42 голосов
/ 22 января 2011

Я получаю ошибку компилятора, когда пытаюсь встроить метод одного из моих классов. Это работает, когда я убираю ключевое слово "inline".

Вот упрощенный пример:

main.cpp:

#include "my_class.h"

int main() {
  MyClass c;
  c.TestMethod();

  return 0;
}

my_class.h:

class MyClass {
 public:
  void TestMethod();
};

my_class.cpp:

#include "my_class.h"

inline void MyClass::TestMethod() {
}

Я пытаюсь скомпилировать с:

g++ main.cpp my_class.cpp

Я получаю ошибку:

main.cpp:(.text+0xd): undefined reference to `MyClass::TestMethod()'

Все хорошо, если я уберу "встроенный". Что вызывает эту проблему? (и как мне встроить методы класса? Возможно ли это?)

Спасибо.

Ответы [ 3 ]

38 голосов
/ 22 января 2011

Тело встроенной функции должно быть в заголовке, чтобы компилятор мог фактически заменить его там, где это необходимо. Смотрите это: Как вы скажете компилятору сделать функцию-член встроенной?

16 голосов
/ 22 января 2011

7.1.2 / 4 стандарта:

Встроенная функция должна быть определена в каждая единица перевода, в которой она находится б ...

Вы используете TestMethod в main.cpp, но он там не определен.

... Если функция с внешней связью объявлен встроенным в одном переводе единица, она должна быть объявлена ​​встроенной в все переводческие единицы, в которых оно появляется; Диагностика не требуется.

Вы определяете (и, следовательно, также объявляете) TestMethod, встроенный в my_class.cpp, но не в main.cpp.

Исправление в этом случае состоит в том, чтобы переместить определение функции в файл заголовка, например, так:

class MyClass {
 public:
  void TestMethod() {}
};

или как это:

class MyClass {
 public:
  inline void TestMethod();
};

inline void MyClass::TestMethod() {}
3 голосов
/ 22 января 2011

Вы определили его как не встроенный в заголовочном файле, в то время как в файле cpp вы пытаетесь определить его как встроенный.Это противоречивое определение, и оно не сможет найти одно из другого.Ваш заголовок - это то место, где вы действительно размещаете ключевое слово inline.

Однако я бы удалил ключевое слово inline, так как в любом случае это действительно больше предложение компилятору.Это действительно нужно, только когда в заголовке есть свободно плавающая функция, и вы не хотите, чтобы в вашей кодовой базе появлялось несколько определений.

...