Vererbung an Klassen in Klassen

lfp

Grünschnabel
Hallo Miteinander!

Mein Problem ist innerhalb meines Projekts nicht leicht zu verstehen, deshalb habe ich ein kleines Programm geschrieben das sich nur auf das eigentliche Problem beschränkt.

Code:
#include<iostream>
using namespace std;

class big_class {
	private:
		//nothing
	public:
		void general_error_to_log_file_function(char* error_description);
		class subdivision {
			private:
				//nothing
			public:
				void any_function ();
		} my_subdivision;
};

void big_class::general_error_to_log_file_function (char* error_description){
	// write the description of the error into the log-file
}

void big_class::subdivision::any_function(){
	//do whatever
	//do whatever
	//do whatever

	if(1){ //if anything goes wrong
		
		general_error_to_log_file_function("error in any_function of subdivision!");

	}
}
int main(){
	big_class my_class;

	my_class.my_subdivision.any_function();
	return 0;
}

Ich denke wer den Code-Block nicht übersprungen hat ahnt schon was mein Problem ist.

Ich habe eine Klasse (hier) big_class die so groß ist, dass sie mir zu unübersichtlich wird und ich sie in unter-classen unterteilen möchte.
Die "Unterklasse" (hier) subdivision muss dabei bei Problemen eine Fehler-Behandlungs-Funktion aufrufen die wiederum Teil der übergeordneten big_class ist.

Beim Compilieren bekomme ich den Fehler "error C2352: Unzulässiger Aufruf einer nicht statischen Memberfunktion"

Ich weiß dass es sowas wie Vererbung gibt und es wohl sowas wie eine Lösung für mein Problem geben könnte, habe auch schon selbst danach gesucht, es aber nicht verstanden bzw. nicht anwenden können.

Könnt ihr mir helfen? Geht das was ich machen will überhaupt? Das ganze erfüllt keinen technischen zweck, es verbessert das fertig compilierte Programm nicht wirklich und ich könnte natürlich auch einfach alle Member der subdivision direkt in die big_class schreiben, nur dadurch wird diese eben unheimlich unübersichtlich und das versuche ich zu verhindern.

Gruß
LFP
 
...und ich könnte natürlich auch einfach alle Member der subdivision direkt in die big_class schreiben, nur dadurch wird diese eben unheimlich unübersichtlich und das versuche ich zu verhindern.

Das sehe ich nicht so.
Ich gehe davon aus, dass die Klasse subdivision eine logische Kapselung von Funktionen oder ähnlichem ist. Jemand der (wie du) die Oberklasse nutzt sollte meiner Meinung nach wissen was sich darunter verbirgt oder sich mit der Klasse beschäftigen. Und dann in der Oberklasse auch nur das nutzen, was die Unterklasse im groben kapselt.
Eine Lösung wie du sie willst ist mir bisher unbekannt, auch wenn ich sowas schonmal in Java gesehen habe. Aber wie schon gesagt ich denke nicht, dass die Oberklasse dadurch lesbarer wird.

Grüße
 
Nagut, ich wollte es euch ersparen aber dann eben die Details zum Hauptprojekt, denn das hier ist ja nur Beispielcode um das Problem übersichtlicher und einfacher zu erklären.

Ich schreibe zur Zeit an einer GameEngine die ich in Form einer Klasse aufbauen möchte. Die Game Engine (also die big_class) beinhaltet unter anderem einen Memory-Manager um sicherzustellen, dass keine unentdeckten Speicherlecks entstehen. Diesen Memory-Manager habe ich "MemoryMan" ganannt, und so gibt es all diese Funktionen und Variablen, die alle zum MemoryMan gehören:

Code:
void* MEMORYMAN_alloc(long size);
void* MEMORYMAN_alloc(long size, VE_data_type specific_type);
void* MEMORYMAN_calloc(long size);
void* MEMORYMAN_calloc(long size, VE_data_type specific_type);
void* MEMORYMAN_realloc(void* pointer, long size);
void MEMORYMAN_release (void* pData);
void MEMORYMAN_release_all ();
void MEMORYMAN_init();
vector<VE_memory_unit> MEMORYMAN_data_data;
int MEMORYMAN_allocated_memory;
bool MEMORYMAN_initiated;

Wie du siehst fangen die alle mit "MEMORYMAN_" an um sie zusammen halten zu können und das nervt, denn wenn ich das alles in einer Klasse hätte könnte ich für irgendeine Funktion der Engine einfach Engine.MemMan.anyfunction() schreiben und das sieht für mich erstens übersichtlicher aus, zweitens könnte ich in Visual Studio haufenweise autofill (ctrl+space) benutzen um nur eine Auswahl der Funktionen zu erhalten die ich auch benötige, und noch viel wichtiger: ich könnte viel einfachere und generellere Funktionsnamen verwenden. "void release ();" ist nicht gerade ein Funktionsname den ich nur einmal in der ganzen Engine brauch.
 
Hi

warum alles als Teil einer riesigen Klasse?
Um Zusammenzufassen kann man ja darüber noch Namespaces verwenden.
Die sind auch unabhängig von Instanzierungen.
 
Aber was spricht denn dagegen, in deiner GameEngine ein Objekt vom Typ *MemoryManager zu halten. Wenn die GameEngine initialisiert wird, wird zugleich das Objekt vom MemoryManager erzeugt und ggf. initialisiert (durch zB. eine Init()-Fkt.). So hast du die Kapselung (was auch einen nachträglichen Austausch oder eine Editierung deutlich erleichtert) und in jeder Klasse auch nur das drinnen stehen, was sie eigentlich machen soll.
Ich habe vor 2 Wochen ein Tutorial gefunden, welches das System sehr ähnlich aufbaut. > Klick mich <
Der Autor hat hier sein Aufbau auf einzelne Module aufgeteilt, die im Endeffekt alle durch eine Oberklasse gesteuert werden. Ein Strukturbild ist relativ weit oben zu sehen.

Grüße
 
Hmm... Danke, das sind zwei sehr gute Vorschläge!

@sheel: Also mit Namespaces kenn ich mich nicht so gut aus, deshalb bin ich erstmal lieber vorsichtig mit solchen Ansätzen. Eine Möglichkeit wäre es aber... Trotztdem Danke!

@Jennestra: Ahh, super Idee die Klassen nicht unterzuordnen sondern für jede Funktion eigene Klasse zu schreiben und ein Hauptklasse die die anderen verwaltet. Ich denke so könnt's klappen. Damit ist mein Problem gelöst.

Nochmal vielen Dank und gute Nacht!
 
@sheel: Also mit Namespaces kenn ich mich nicht so gut aus, deshalb bin ich erstmal lieber vorsichtig mit solchen Ansätzen. Eine Möglichkeit wäre es aber... Trotztdem Danke!
Vom Prinzip her mein ich das Gleiche wie Jennesta,
nur dass du alle Klassen deiner Engine noch zusammen in einen Namespace packst
(um letztendlich auch zu ermöglichen, dass zB. andere Programmteile auch einen Memoryman etc. haben, ohne mit den Klassennamen/Variablennamen dieses Teils in Konflikt zu kommen;
und damit man erkennt, wo der Memoryman dazugehört)
 
Zurück