Создание дочернего класса в качестве родительского, но вызов методов ребенка - PullRequest
0 голосов
/ 23 мая 2009

Я пишу приложение, которое требовало разработки движка для обработки данных, но этот движок должен был быть заменен другим, в зависимости от потребностей клиентов. Поскольку у каждого клиента были совершенно разные потребности, я хотел отделить каждый двигатель от других, чтобы мы могли доставить приложение только с теми двигателями, которые требовал клиент.

Итак, мое VS Solution имеет следующие проекты: App, Engine_Base, Engine_A, Engine_B Приложение = exe Engine_Base = родительский класс ... компилируется в dll и добавляется к ссылкам приложения через свойства проекта Engine_A и Engine_B оба являются дочерними классами Engine_Base и оба компилируются в свои собственные dll (Engine_A.dll, Engine_B.dll). Они не добавляются в ссылки на приложение, поэтому они не будут загружены во время выполнения, поскольку мы не хотим отправлять их всем нашим клиентам.

На основании файла конфигурации клиента мы решаем, какой двигатель загрузить:

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

Поскольку к ссылкам проекта C ++ добавляется только Engine_Base, мы приводим наши объекты Engine__A или Engine_B к родительскому типу.

Затем мы устанавливаем События для многопоточного исполнения наших механизмов, так как они требуют много времени для запуска (много данных для обработки):

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

Но это дает мне:

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

Я понимаю, что это связано с наследованием, но мне не хватает идей, как это исправить.

У кого-нибудь есть идеи, как это исправить?

Является ли наш подход хорошим решением или мы должны были смотреть на что-то другое и делать что-то иначе?

1 Ответ

0 голосов
/ 23 мая 2009

Редактировать: Может быть, убедитесь, что методы Engine_A и т. Д. Помечены как виртуальные?

...