2010-06-26 2 views
0

Рассмотрим этот кодВстраиваемые конструкторы? Объяснить такое поведение [C++]

#include <iostream> 
#include <cstdio> 
using namespace std; 

class Dummy { 
public: 
    Dummy(); 
}; 

inline Dummy::Dummy() { 
    printf("Wow! :Dummy rocks\n"); 
} 

int main() { 
    Dummy d; 
} 

Все хорошо здесь!

Теперь я делаю эту модификацию. Я переношу объявление Dummy на «dummy.h».

class Dummy { 
public: 
    Dummy(); 
}; 

и определить конструктор пустышки() следующим образом в "dummy.cpp"

#include "dummy.h" 
inline Dummy::Dummy() { 
    printf("Wow! :Dummy rocks\n"); 
} 

И, наконец, у меня есть мой главный файл как:

#include <iostream> 
#include <cstdio> 
#include "dummy.h" 
using namespace std; 

int main() { 
    Dummy d; 
} 

Он компилирует хорошо, но я получаю ошибку компоновщика, жалуясь на неопределенную ссылку на Dummy :: Dummy().

Любые идеи.

-

ответ

3

Вы должны поместить все встроенные функции (включая методы и конструкторы/деструкторы) в файле заголовка, в котором они объявлены.

Хотя этот код должен работать в любом случае, с main(), вызывающим конструктор, как если бы ключевое слово inline не было. Вы уверены, что передаете объектные файлы из обоих блоков компиляции в компоновщик?

+0

yesah.it работает с ключевым словом inline, удаленным из конструктора, что явно подразумевает, что компоновщик получает как объектные файлы, Что касается определения встроенных методов в заголовке, я вижу вашу точку, однако я удивляюсь, что он работает с другими функциями и просто Обратите внимание на конструктор? – sud03r

+0

@Neeraj Это проблема, потому что эти другие функции использовались только в том же файле .cpp, что и встроенные функции. – 5ound

+0

@above correct .. – sud03r

0

Попробуйте удалить встроенный спецификатор из файла реализации. Если мое понимание верное, вы можете только встроить в заголовок

+0

Ваше понимание частично правильно. Чтобы функция была встроена, ее определение должно быть видимым в блоке компиляции до его использования (т. Е. В заголовке с объявлением). Но даже если это не так, определение в * другой * компиляционной единице создаст внеуровневый экземпляр функции, а первый блок компиляции просто вызовет этот экземпляр так, как если бы ключевое слово 'inline' не было. – slacker

+0

Спасибо за разъяснение. – nathan

+0

@slacker: определение в другом блоке компиляции * может * создать экземпляр вне строки. Не указано, действует ли оно или нет, а код, который опирается на него, является неформальным. –

2

Вы должны подумать, как компиляция работает на C++ и идея отдельных единиц компиляции, используемых на C++, и инкапсуляция, полученная с использованием заголовков и файлов cpp.

Посмотрите здесь: http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.6

Рядный говорит компилятором, что вместо вызова функции «копировать - вставить» свой код в месте вызова функции. Когда вы вставляете встроенное определение в файл CPP, он не будет отображаться при связывании с другими скомпилированными единицами (его в файле cpp не в h-файле), поэтому компилятор понимает из подписи, помещенной в классе, что нет никаких параметров Con's поэтому он не будет реализовывать значение по умолчанию. Но компоновщик не может найти тело функции, потому что оно реализовано inline в файле cpp.

Смежные вопросы