[C++] TimeService - Tücken der Vererbung

Valium110

Lieutenant
Registriert
März 2001
Beiträge
898
Hallo Leute!

Hallo Leute hab mal eine Frage Richtung Objektorientierung:

Ich will eine Basisklasse erstellen , die es den Objekten der der Klassen die von ihr geerbt haben ermöglicht die Lebensdauer des jeweiligen Objektes zu bestimmen. Also ein TimeService, der Programmierer unterstützt.
Das ganze soll im Grunde dann so ablaufen, dass ich in der Basisklasse eine Variable habe in dem ein Zeitstempel gesetzt wird wenn der Konstruktor aufgerufen wird. Soweit so Gut!

1. Frage
Eine weitere Funktion soll jedoch sein, dass ich die Aktive Zeit eines Objektes bestimmen kann (Also: Wie lange hat es gedauert mit dem Objekt zu arbeiten?). Das ganze muss ja dann so ablaufen, dass vor und nach dem Aufruf einer jeden Funktion (die aber nur in der Tochterklasse vereinbart ist) eine Funktion der Basisklasse gestartet wird (die dann die Zeiten stoppt).
Frage, wie kann ich das machen?

2.Frage:
Außerdem soll es mögliche sein, eine Liste aller Objekte (und auch aller Objekte eines Typs) zu generieren, die von der Basisklasse geerbt hatten. Das Verwalten einer Liste mit Zeigern auf die Objekte stellt kein Problem dar, wohl aber die Unterscheidung des Typs. In der Basisklasse muss ich also unterscheiden können von welchem abgeleiteten Klassentyp ein Objekt ist. Gibt es da eine Möglichkeit? Die abgeleiteten Klassen sollen dabei frei erstellbar sein (Ich weiß nicht, wie die Klassen heißen und wie sie implementiert sind). (Ich muss "nur" die Objekte verschiedener Klassen unterscheiden können)

Danke schon mal für eure Mühen!
 
Zu 1) Versteh nicht genau was du meinst. Bitte erklär mal genauer was du willst. :confused_alt:

Zu 2) Du könntest doch in den Tochterklassen eine Schnittstelle vorgeben in der Art von
Code:
Type getType()
und dir dann eine enumeration zurückgeben lassen, oder eben eine TypeID, anhand der nachvollziehbar ist was für einer Klasse das Objekt angehört.
 
Zu 1.: Ich glaube, ich verstehe, was Du willst. Allerdings wirst Du das alles selbst programmieren müssen, dafür gibt es keinen Automatismus. D.h. Du rufst eine beliebige Funktion auf, und diese fordert dann wie alle anderen von der Vaterklasse das Messen der Zeit an. Hierbei musst Du eines beachten: Die Aufrufe werden sich sicherlich schachteln können. D.h. eine Methode ruft eine andere Methode des Objektes auf. Hier musst Du dann mit einem Stack oder ähnlichem arbeiten. Denk daran, dass ganze Exception-safe zu machen (also dass der Stack im Falle einer Exception auch wieder korrekt abgebaut wird).

Zu 2.: Da hat GreenMamba schon im Prinzip recht. Allerdings muss die Funktion in die Basisklasse und so aussehen:
Code:
virtual Type getType() const;
Je nach dem, ob die Basisklasse abstrakt ist oder nicht, kannst Du auch diese Methode abstrakt machen.

@GM: An deinen neuen Avatar werd ich mich wohl nie gewöhnen :freak:
 
Noch mal eine Präzisierung der Anforderungen an die Basisklasse.

Ich erstelle nur die Basisklasse! Die Sohnklassen sind bei der Erstellung unbekannt und in ihnen soll möglichst nichts für den TimeService gemacht werden, außer die Abfragen der Variableninhalte (z.B. Erstellungszeit, gewünschte Lebensdauer usw.)! Alles was mit der eigentlichen Verarbeitung zu tun hat, soll für alle Objekte der Sohnklassen in der Basisklasse erfolgen. Es gibt es keine Objekte der Basisklasse.

Ich müsste ermitteln, von welchem Typ die Sohnklassen sind, um sie geordnet in Listen zu packen (geordnete Ausgabe der Objekte eines Typs/aller Objekte nach Lebensdauer).

Nochmal zu Frage 1:
Es soll ermittelt werden, wie lange an den einzelnen Objekten gearbeitet wurde (Summe der reinen Bearbeitungszeit). Also wenn ich eine Methode des Objektes aufrufe, soll die Zeit gestoppt werden, die er zur verarbeitung der Methode benötigt. Dies soll automatisch erfolgen (also ohne Aufruf von benötigten Methoden der Basisklasse:

z.B. so nicht:

Basis::Start (Start des Timers)
Sohn::Methode (Eigentlicher Methodenaufruf)
Basis::Stopp (Stopp des Timers und Aktualisierung der entsprechenden Zeitvariable)

Vielmehr soll der Entwickler der Sohnklassen einfach seine Methoden ausführen ohne die Basisklassenmethoden explizip aufzurufen.

=> also benötige ich eine Möglichkeit aus der Basisklasse heraus zu erkennen, ob eine Sohnmethode aufgerufen wird und endet, um dann automatisch die entsprechenden Methoden der Basisklasse aufrufen zu können. Gibt es da eine Möglichkeit?
 
Nein. Keine mir bekannte Möglichkeit. Auf jeden Fall für das was du willst. Wenn alle Methoden aller Sohnklassen genau die selbe Signatur hätten, könnte man eventuell an eine Geschichte mit Templates denken. Aber da fällt mir spontan auch noch nichts zu ein.

Dein Problem ist übrigens ein ganz klassisches. Eine immer wiederkehrende Codeform von
TueEtwasGemeinsames
TueEtwasVölligUnterschiedliches
TueEtwasGemeinsames

Dieses Codeschema tritt in der Praxis sehr oft auf, lässt sich aber nicht so lösen, wie Du es dir vorstellst. Der Grund ist: Man kann nicht etwas aufrufen, was man nicht kennt und was völlig unterschiedlich ist.

Lösung:
Man könnte hier an Wrapper-Klassen denken. D.h. Du legst mit Beginn der Funktion ein Objekt an, das den Timer startet. Wenn das Wrapper-Objekt seinen gültigkeitsbereich verliert, also wenn die Funktion zuende ist, stoppt es den Timer wieder in seinem Destruktor. Dadurch musst Du aber immernoch in jeder Funktion einen Wrapper anlegen. Darum wirst Du nicht drum rum kommen.
 
Zuletzt bearbeitet:
Danke erstmal für die Mühe mit der 1. Frage.

Zur Frage 2:

virtual Type getType() const;

Um das zu realisieren müsste ich dem Entwickler ja anweisen entsprechende Schnittstellen zu Programmieren, was wiederum der Anforderung der Einfachheit nur schwer gerecht wird!
Gibt es noch andere Möglichkeiten, z.B. über Templates, mit denen ich herausfinden kann, ob ein Objekt von einem oder vom anderen Typ ist?
 
Ja, müsste man, das geht nicht anders. Allerdings, eine Basisklasse, die etwas über ihre Sohnklassen weiß, ist kein wirklich guter Entwurf, weil Du die Vererbundsrichtung aufbrichst. Vielleicht solltest Du Deine Klassen einfach nochmal neu planen. Ist es wirklich nötig, dass alle von Deiner Time-Klasse ableiten?
 
Naja, wenn es um Messungen im Sekundenbereich geht, kann man mit GetTickCount nicht mehr viel anfangen, da der Counter sehr ungenau ist. (55ms Takt) Zudem läuft er auch nicht wirklich synchron zur Uhrzeit. Kommt aber ganz auf die benötigten Zeiten an.

Falls es um Zeiten im Millisekundenbereich geht, ist man mit QueryPerformanceCounter / QueryPerformanceFrequency gut beraten. (Falls es überhaupt um Windows geht :))
 
Hi,

@7H3 N4C3R

über die genauigkeit hat er sich ja nicht ausgelassen, und für normale Zeitermittlungen wird gettickcount reichen. Normalerweise wenn ich die Zeiten die eine Routine zum ablaufen braucht ermitteln muss, geht es ja darum das es zu lange dauert und nicht weil sie zu schnell läuft, oder?

Gruß

Toaster
 
Zurück
Oben