2015-07-04 4 views
0

у меня есть три файла - основные, заголовок и его «реализации»:Правильный способ для реализации функций-членов

// main.cpp 
#include "word_indexer.h" 

int main() { 
    WordIndexer wd; 
    cout << wd.size() << endl; 
    return 0; 
} 

// word_indexer.h 
class WordIndexer { 
public: 
    int size() const; // declaring a function 
}; 


// word_indexer.cpp 
class WordIndexer { 
public: 
    int size() const {return 0;} 
}; 

здание с g++ -o main main.cpp word_indexer.cpp выходами

неопределенная ссылка на «WordIndexer :: размера() Const»

Замена реализации с

// updated word_indexer.cpp 
class WordIndexer { 
public: 
    int size() const; 
}; 

int WordIndexer::size() const {return 0;} 

исправляет проблему. Я не могу понять разницу между этими word_indexer.cpp и его обновленными версиями, они кажутся одинаковыми.

Почему у первого варианта есть проблемы с связыванием?

+1

Btw: У вас заголовок должен иметь [включить охрану] (https://en.wikipedia.org/wiki/Include_guard). –

ответ

3

Нет необходимости повторять определение класса в его файле реализации. Просто надо его включать заголовок класс, определенный в, а затем определить функции члена в файле реализации как:

// word_indexer.cpp 
#include "word_indexer.h" 
int WordIndexer::size() const {return 0;} 

А почему первый вариант не сработал: Функции-члены, определенные в классе неявно inline. Таким образом, их определения должны присутствовать в каждой единицы перевода, которая их использует. Вот почему это работает, если вы определяете член в классе в файле заголовка, но не, если у вас есть только встроенное определение в другом файле .cpp.

+0

Спасибо! Есть ли способ реализовать класс в этом встроенном стиле, не делая методы класса действительно встроенными (в смысле компилятора)? Моя цель - сохранить формат .h/.cpp, избегая при этом префикса 'WordIndexer ::'. – DimG

+0

@DimG Нет, и вы * действительно * не должны указывать определение класса в файле .cpp. Либо определите функцию в классе в заголовке, либо выполните операцию префикса в .cpp. Кроме того, префикса на самом деле не так уж плоха, если вы получаете редактор с хорошей функцией автозаполнения (которую я очень рекомендую). –

2

Вот как это делается для классов.

Header (word_indexer.h):

// declare the class and all its methods, member variables, etc. 
class WordIndexer { 
public: 
    int size() const; // declaring a function, but not its implementation 
}; 

Реализация (word_indexer.cpp):

// the implementation basically takes the header "skeleton" and fleshes it out; 
// to do that, of course, we need the skeleton first 
#include "word_indexer.h" 

// we don't need to say "class WordIndexer {}" or anything like that, 
// because that's already been done in the header we included 

// implement the method 
int WordIndexer::size() const {return 0;} 
1

В word_indexer.cpp вы должны написали что-то вроде:

int WordIndexer::size() const {return 0;} 

Это синтаксис фактического определения.

И вместо обновления WordIndexer в единицах перевода, всего #include "word_indexer.h".

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