Prosty object tracing
• tech • 368 słów • 2 minuty czytania
Potrzebowałem w prosty sposób i łatwy sposób logować moment tworzenia i niszczenia obiektów. W najprostszym wypadku wystarczyłoby przeciążyć operator new i delete, ale wtedy logowanie dotyczyłoby tylko obiektów tworzonych na stercie. A ja chce i stos, i stertę ;)
No to wystarczy w konstruktorze i destruktorze umieścić wywołanie funkcji logującej i problem znika. Tylko, że w każdej klasie musimy dodać ten kod, a jak wspomniałem sposób powinien być najprostszy i najłatwiejszy.
W takim razie szablonowa klasa podstawowa z logowaniem w konstruktorze i destruktorze? Tak, to będzie dobry pomysł, ale co tak naprawdę zyskujemy w porównaniu do wrzucania kodu w każdą klasę? Skoro tutaj też musimy zadbać, aby nasza klasa dziedziczyła po tej klasie z logowaniem. Zyskamy jedynie możliwość szybkiej zmiany i rozbudowy funkcji logującej, bo wystarczy wtedy tylko zmienić w jednym miejscu, a nie szlajać się po całym kodzie projektu.
Głównym celem naszego object tracingu jest wypisywanie w logu informacji jaki obiekt został stworzony i zniszczony, dlatego musimy znać nazwę danej klasy pochodnej.
Możemy pokombinować coś z Quoted Literals as Template Arguments, ale nie bardzo to nadaje się do naszego przypadku, przynajmniej mi nie udało się z tym nic zrobić ;) Zatem możemy skorzystać z makr lub RTTI. Wszakże trading potrzebny jest nam w wersji debug, zatem w wersji finalnej nie będzie żadnych dodatkowych kosztów w czasie działania.
Nasza szablonowa klasa bazowa mogłaby wyglądać tak:
template<typename T>
class ObjectTracing {
public:
ObjectTracing() {
::LogTrace("%s created", typeid(T).name());
}
~ObjectTracing() {
::LogTrace("%s destroyed", typeid(T).name());
}
};
A jej użycie bardzo proste:
class MyClass : public ObjectTracing<MyClass> {
// ...
};
Oczywiście znakowa reprezentacja nazwy pobrana metodą name() obiektu type_info zależy od implementacji, dlatego może zostać wzbogacona o jakieś dodatkowe prefiksy lub sufiksy.
W moim programie korzystam z wxWidgets, dlatego swój kod oparłem o RTTI (a raczej jej namiastce) tejże biblioteki, które w wolnym tłumaczeniu polega na umieszczaniu za pomocą makr statycznych pól w klasie z informacjami o jej typie i właściwościach. W sumie mechanizm object tracingu potrzebny mi jest tylko w wersji debug, także zadbam o to, aby w moich klasach nie dziedziczących po wxowych, w wersji release pola z danymi RTTI się nie pojawiły. Bo i tak tylko jest mi ono potrzebne do tracingu.
Nic nowego nie wymyśliłem ;)
Komentarze (0)