Prosty object tracing

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 ;)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *