Mam prostą klasę i typ wyliczeniowy. Klasa jest pozbawiona metod by nie zaciemniać problemu. W niej jeden getter i setter. Gettery i settery są to (zazwyczaj) proste metody o minimalnej ilości kodu więc warto je definiować jako inline. Jeśli klasę zdefiniuję całą w pliku .h
to wszystko jest dobrze. Jeśli oddzielę definicje od deklaracji i przeniosę je do pliku .cpp
ale bez słowa inline
to też jest dobrze (w sensie kompilacja i linkowanie bez ostrzeżeń i błędów). Ale jeśli chciałbym oddzielić deklaracje od definicji i dodatkowo oznaczyć setter i getter jako inline
czyli jeśli robię to tak jak poniżej…
golccell.h
#ifndef GOLC_CELL_H
#define GOLC_CELL_H
enum Direction { N, E, S, W, EMPTY };
class Cell {
public:
Direction getDirection() const;
void setDirection(Direction direction);
private:
Direction direction = EMPTY;
};
#endif
golccell.cpp
#include "golccell.h"
inline Direction Cell::getDirection() const {
return direction;
}
inline void Cell::setDirection(Direction direction) {
Cell::direction = direction;
}
to pojawia się błąd przy linkowaniu o następującej treści:
/tmp/ccq8WcAE.o:main.cpp:(.text+0x21): undefined reference to `Cell::setDirection(Direction)'
/tmp/ccq8WcAE.o:main.cpp:(.text+0x21): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Cell::setDirection(Direction)'
/tmp/ccq8WcAE.o:main.cpp:(.text+0x2d): undefined reference to `Cell::getDirection() const'
/tmp/ccq8WcAE.o:main.cpp:(.text+0x2d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Cell::getDirection() const'
collect2: error: ld returned 1 exit status
Mogę te definicje dać w pliku .h
ale jednak zależy mi na tym by oddzielić definicje od deklaracji tym bardziej, że sama klasa jest dużo bardziej złożona i nie chciałbym mieć część definicji tu, a pozostałą część tu.
O co chodzi z tym "niezdefiniowanym symbolem" i jak umieścić definicje tych dwóch metod w pliku .cpp
tak, żeby dały się oznaczyć jako inline
?
PS. Wiem, że inline
jest tylko sugestią i nie mam pewności, że kompilator rozwinie ich ciało włączając bezpośrednio w kod je wywołujący (jak i w druga stronę). Ale chciałbym to jednak ładnie pogrupować.
PS2.
main.cpp
#include <iostream>
#include "golccell.h"
int main() {
Cell cell;
cell.setDirection(Direction::N);
std::cout << cell.getDirection() << std::endl;
return 0;
}
Kompiluję jako: g++ -std=c++11 main.cpp golccell.cpp