Jak w C++ zrobić zdarzenie, które obserwuje stan zmiennej i wykonuje funkcję w razie zmiany wartości zmiennej, np. mam int iente = 1;
Generalnie nie wiem, jak to wygląda w Qt. Ale sam wzorzec jest prosty zeby zapisać go w dowolnym języku: http://www.dreamincode.net/forums/topic/197421-the-listener-pattern/
Jednak to nie będzie dobre rozwiązanie.
Uzasadnij, dlaczego uważasz, że Observer Pattern jest złym podejściem do rozwiązania tego problemu?
Lepszy do czego? W każdym języku którego używałem asynchroniczny event na zmianę stanu obiektu był mniej lub bardziej wzorowany właśnie na OP. Przykład Java: http://docs.oracle.com/javase/7/docs/api/java/beans/PropertyChangeListener.html
Poza tym zmieniasz informację o tym czego oczekujesz. Poprzednio mówiłeś, że potrzeba ci, aby wiedzieć, że nastąpiła zmiana właściwości obiektu. Teraz, aby mieć dostęp do tego drugiego obiektu. Dostęp do obiektów z reguły uzyskuje się przez przekazanie referencji/wskaźnika do konstruktora obiektu. Dzięki temu obiekt A może manipulować metodami obiektu B (B jest polem w A).
Tym jest właśnie OP. Cechy obserwatora są dziedziczone/interfejsowane zapewniając ponowne użycie kodu.
Wybacz, nie rozumiem o co tobie tu chodzi. Oprogramować musisz tylko co ma się stać, jak coś się zmieni w stanie obiektu.
EDIT
Znalazłem jak zaleca zrobić to Qt. Signals and slots: http://en.wikipedia.org/wiki/Signals_and_slots
A tu pierwsze zdanie:
Więc jak dla mnie masz dwa wyjścia:
-
przeczytać jak używać Observer Pattern i go użyć (i będziesz mógł tego używać niezależnie od języka programowania).
-
użyć tego co zaleca Qt, mając na uwadze, że jest to w zasadzie punkt pierwszy, tylko chowa przed tobą implementację dwóch klas tak na dobrą sprawę.
Dlatego:
Zmieniam, bo to wydaje mi się zbyt skomplikowane jak na moje potrzeby.
Mam dużo klas które się komunikują z klasą okna, muszę im wszystkim przypisać wskaźniki do okna, zaprzyjaźnić je z klasą okna. Wydaje mi się, że to się powinno robić znacznie prościej.
Jak mam kilka QLineEdit i je mam zmieniać za pomocą specjalnych ekstra funkcji (o ile nie mam przypisać wskaźników i przyjaźni) to znów wydaje się, że lepiej to zrobić inaczej.
Trochę tego nie ogarniam, chciałbym aby ktoś mnie pokierował.
Zadałeś sobie trud, by przeczytać mój post ze zrozumieniem? Observer pattern, w Qt: signals & slots. Po googluj za tymi hasłami.
EDIT
W ciągu pół minuty powinieneś zaleźć to: http://qt-project.org/doc/qt-4.8/signalsandslots.html
Ja mam problem, że sobie wymyśle rozwiązanie, ale nie wiem jak to nazwać albo jest niemożliwe.
Czytałem o tym, nawet używam sygnałów i slotów przy pobieraniu danych z neta. Myślałem tylko, że ekstra do tego da się to zrobić łatwej/lepiej.
Np. wydawało mi się, że może istnieć rozwiązanie w stylu JS czyli: zmienna.addEventListener(“changeValue”, funkcja, false);
To by było proste i wygodne, ale żeby osiągnąć takie coś to by trzeba napisać więcej kodu a i tak by działało inaczej niż bym chciał.
Sygnały i sloty w ogóle tego by nie potrafiły.
Nerwy mi powoli puszczają, takim addEventListener jest własnie w slotach connect…
EDIT
Nie do końca rozumiem. Oczekujesz możliwości podpięcia czegoś pod typ prymitywny? To przecież 4 bajty. W JavaScriptcie, int to nie int tylko jakiś tam obiekt który ma tablicę prototypów i inne takie duperele, dzięki czemu piszesz krótszy kod, to prawda i 20 razy wolniejszy dzięki temu. Musisz coś wybrać, imho C++ przy rozterkach pt. “mój kod jest długi” radziłbym sobie odpuścić. Może python, groovy albo scala?
nie musi być int, mogę specjalny obiekt sobie zrobić do tych wartości które będą obserwowane.
Ja tak naprawdę używam QT tylko dlatego, że dzięki temu mogę mieć nieduże pole-widget w nietypowym miejscu w systemie (konkretnie to z lewej strony traya, w wolnym miejscu na pasku zadać Windows 7). Gdyby się dało to bym używał JavaScript (wiem że się da osadzić pole webowe, chyba nie warto mieszać).
Poznaję przy tym C++ QT itd, ale nie jestem entuzjastą. Nie jest to ważne w sumie ale tak sobie napisałem.
Zrobię funkcję publiczną w klasie okna i wystarczy, nie wiem czemu tak tego unikałem.
Sygnały to nic nadzwyczajnego, równie dobrze mogę bezpośrednio wywoływać taką właśnie funkcję.
Coś zyskam na tych sygnałach w tym przypadku?
Na zdrowy rozum, gdyby nie istniała potrzeba, a wywoływanie synchroniczne sprawdzało się, to nie powstałby wzorzec tylko wszyscy wywoływali funkcję. Jednak wzorzec powstał, mało tego każda biblioteka tworzona w duchu MVC, go używa.
Przede wszystkim takie wołanie funkcji prowadzi do brzydkiego zapachu w kodzie, o nazwie “tight coupling”. To podejście, które proponujesz jest nieskalowalne w przypadku jednego broadcastera i wielu reciverów. Dodatkowo chciałbym zobaczyć jak twój kod robi się coraz piękniejszy kiedy przykładowo musisz dla jakiegoś elementu zaprzestać nasłuchiwania, normalnie odpinasz listener, a z synchronicznym wywołaniem powstanie ładna gromadka ifów.
EDIT
Jeszcze mały link, który może więcej powie, co jak dlaczego: http://www.dcs.bbk.ac.uk/~oded/OODP13/Sessions/Session6/Observer.pdf