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)

Dodaj komentarz

/dozwolony markdown/

/nie zostanie opublikowany/