2009-05-22 3 views
0

Ich schreibe eine Anwendung, die die Entwicklung einer Engine für den Umgang mit Daten benötigt, aber die Engine musste je nach Kundenbedürfnis durch eine andere ersetzt werden können. Da jeder Kunde sehr unterschiedliche Bedürfnisse hatte, wollte ich jeden Motor getrennt von den anderen machen, so dass wir die Anwendung nur mit den Motoren liefern konnten, die der Kunde benötigt.Instantiieren einer Kindklasse als Eltern, aber Aufruf der Methoden des Kindes

Also meine VS-Lösung hat folgende Projekte: App, Engine_Base, Engine_A, Engine_B App = die exe Engine_Base die übergeordnete Klasse = ... kompiliert in eine DLL und wird auf die Referenzen der App durch die projec hinzugefügt Eigenschaften Engine_A und Engine_B sind beide untergeordnete Klassen von Engine_Base und beide kompilieren zu einer eigenen DLL (Engine_A.dll, Engine_B.dll). Sie werden den Referenzen der App nicht hinzugefügt, so dass sie zur Laufzeit nicht geladen werden, da wir nicht an alle unsere Kunden versenden möchten.

Basierend auf der Konfigurationsdatei des Kunden sind wir, die Maschine zu laden entscheiden:

Engine_Base^ engine_for_app; 
Assembly^ SampleAssembly; 
Type^ engineType; 

if (this->M_ENGINE == "A") 
{ 
    SampleAssembly = Assembly::LoadFrom("path\\Engine_A.dll"); 

    engineType = SampleAssembly->GetType("Engine_A"); 
    engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2)); 
} 
else 
{ 
    SampleAssembly = Assembly::LoadFrom("path\\Engine_B.dll"); 

    engineType = SampleAssembly->GetType("Engine_B"); 
    engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2, param3, param4)); 
} 

zu den Referenzen des C++ Projekt Da nur hinzugefügt Engine_Base werfen wir unsere Engine__A oder Engine_B an die Muttertyp-Objekte.

Dann setzen wir die Ereignisse für die Gewindeausführung unserer Motoren, da sie eine lange Zeit in Anspruch nehmen zu laufen (viele Daten zu verarbeiten):

engine_for_app->OnComplete += gcnew CompleteEngineProcess(this, &frmMain::ThreadChildComplete); 
engine_for_app->OnProgressInit += gcnew ProgressInitEngine(this, &frmMain::ThreadChildProgressInit); 
engine_for_app->OnProgressReport += gcnew ProgressReportEngine(this, &frmMain::ThreadChildProgressReport); 

Thread^ aThread; 
aThread = gcnew Thread(gcnew ThreadStart(engine_for_app, &Engine_Base::Read)); 

Aber das gibt mir ein:

Error 2 error C3754: delegate constructor: member function 'Engine_A::Read' cannot be called on an instance of type 'Engine_Base ^' d:\_activeWork\EDI_TRUNK\src\App\frmMain.cpp 492 

Mir ist klar, dass dies mit der Vererbung zu tun hat, aber ich habe keine Ideen, wie ich das beheben kann.

Hat jemand Ideen, wie man das beheben kann?

Ist unser Ansatz eine gute Lösung oder hätten wir etwas anderes suchen und die Dinge anders machen sollen?

+0

Ich kann dieses Problem in C++ nicht reproduzieren. Ich habe eine abstrakte Basisklasse mit einer virtuellen Methode und zwei abgeleiteten Klassen erstellt. Ich kann dann eine abgeleitete Klasse instantiieren und dieselbe Syntax verwenden, die Sie zum Ausführen eines Delegaten verwendet haben, das auf die Basis der virtuellen Methode verweist. Können Sie die relevanten Teile der Definitionen von Engine_Base, Engine_A und Engine_B veröffentlichen? –

+0

Dies ist verwaltet C++ und Markieren der Funktionen als virtuelle hatte keine Auswirkungen auf das Verhalten. Das Markieren der Basisklasse als virtuell gibt den folgenden Fehler: Fehler Fehler C2889: 'Engine_Base': ein verwalteter Klassentyp kann keine virtuelle Basisklasse –

Antwort

0

Edit: Vielleicht sicherstellen, dass Engine_A, etc. Methoden als virtuell markiert sind?

+0

Die verwendete Engine ist dynamisch, es muss als die Basisklasse in angegeben werden Code. –

+0

Verstanden. Sie sind sicher, dass die Methode als virtuell markiert ist. – PiNoYBoY82

+0

Das Markieren der Funktionen als virtuell hatte keine Auswirkung auf das Verhalten. Das Markieren der Basisklasse als virtuell gibt den folgenden Fehler: Fehler Fehler C2889: 'Engine_Base': ein verwalteter Klassentyp kann keine virtuelle Basisklasse sein –

Verwandte Themen