Napisałem dla siebie implementację wzorca Builder rozkładając go na dwa pliki. Napisałem go w ten sposób (tylko jedna metoda, żeby nie zaciemniać):
builder.h:
#ifndef BUILDER_H
#define BUILDER_H
#include "shape.h"
//class Shape;
class Builder {
public:
Builder& setSides(int sides) {
this->sides = sides;
return *this;
}
int getSides() const {
return sides;
}
Shape* build() {
return new Shape(*this);
}
private:
int sides;
};
#endif
shape.h:
#ifndef SHAPE_H
#define SHAPE_H
//#include "builder.h"
class Builder;
class Shape {
public:
Shape(const Builder& builder): sides(builder.getSides()) {}
int getSides() const {
return sides;
}
private:
int sides;
};
#endif
W klasie Builder
mam odwołanie do klasy Shape
, ale i w klasie Shape
mam odwołanie do klasy Builder
. Gdy mam tak jak teraz czyli w pliku builder.h
jest include, a w pliku shape.h
jest forward declaration, to mam takie komunikaty błędów:
In file included from builder.h:4:0,
from main.cpp:1:
shape.h: In constructor ‘Shape::Shape(const Builder&)’:
shape.h:9:42: error: invalid use of incomplete type ‘const class Builder’
Shape(const Builder& builder): sides(builder.getSides()) {}
^~~~~~~
shape.h:5:7: note: forward declaration of ‘class Builder’
class Builder;
^~~~~~~
A gdy jest na odwrót (w pliku builder.h
jest forward declaration, a w pliku shape.h
jest include) to mam takie:
In file included from main.cpp:1:0:
builder.h: In member function ‘Shape* Builder::build()’:
builder.h:19:31: error: invalid use of incomplete type ‘class Shape’
return new Shape(*this);
^
builder.h:5:7: note: forward declaration of ‘class Shape’
class Shape;
^~~~~
Nie wiem już co robić. Oczywiście jak wrzucę te klasy do jednego pliku to jest ok ale specjalnie chcę je mieć oddzielnie. Jak to zrobić żeby działało? Próbowałem już chyba każdej kombinacji includów i forward declaration. Najlepsze jest to, że w necie pełno jest odpowiedzi ale wszystkie są napisane dla jednego pliku. Tak to mnie też działa ale nie o to mi chodzi.
Całość wywołuję jako:
Builder builder;
Shape* shape = builder.setSides(4).build();