Ich möchte Gesetz der Demeter befolgen. Aber ich würde auch gerne einige Objekte laden, die an Konstruktoren übergeben werden. Wie soll ich das umsetzen? Eine Wrapperklasse übergeben? Einen Funktionszeiger übergeben?Wie man faul lädt unter Einhaltung des Demeter-Gesetzes?
4
A
Antwort
2
können Sie schreiben, tatsächlich eine allgemeine Wrapper, dies zu erreichen:
template <typename T>
class Lazy {
public:
explicit Lazy(T const& t): _loader(), _item(t) {}
explicit Lazy(T&& t): _loader() _item(t) {}
explicit Lazy(std::function<T()> l): _loader(l), _item() {}
T& operator*() { return this->get(); }
T const& operator*() const { return this->get(); }
T* operator->() { return &this->get(); }
T const* operator->() const { return &this->get(); }
private:
T& get() { if (not _item) { _item = _loader(); } return *_item; }
T const& get() const { if (not _item) { _item = _loader(); } return *_item; }
std::function<T()> _loader;
mutable boost::optional<T> _item;
}; // class Lazy
Diese Klasse garantiert, dass der Lader einmal ausgeführt wird, solange es vervollständigt. Wenn es nicht abgeschlossen wird, wird die Ausführung beim nächsten Zugriff wiederholt. Es ist nicht threadsicher.
Verbrauch:
// Output prime numbers as text
bool isPrime(int);
std::string toEnglish(int);
void print(int i, Lazy<std::string> const& heavy) {
if (not isPrime(i)) { return; }
std::cout << *heavy << "\n";
}
int main(int argc, char* argv[]) {
if (argc < 2) { return 1; }
int max = atoi(argv[1]);
for (int i = 2; i <= max; ++i) {
print(i, [=](){ return toEnglish(i); });
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++11 lambda syntax
}
}
Hier wird toEnglish
immer nur für Primzahlen aufgerufen.
Danke, können Sie ein Beispiel für die Verwendung geben? Ich kann es kompilieren, habe aber keine Ahnung, wie man es benutzt. – fxam
@fxam: sicher, hier gehen Sie :) –
'Get()' ist privat, so dass Sie es nicht einfach in 'print' verwenden können. :) Ich habe das 'private:' um zwei Zeilen nach unten verschoben, da ich denke, dass du das eigentlich wolltest. Revert wenn nicht. Ich habe auch das Lambda geändert, da du eigentlich 'i' fangen musst. – Xeo