Описание: В поисках стандартного шаблона проектирования C ++ для загрузки различных файлов через конструктор
У меня есть класс Base
с некоторыми функциями, которые будут использоваться всеми производными классами (например, Derived_A
, Derived_B
).Принципиальное отличие состоит в том, что Derived_A
и Derived_B
переопределяют функцию load
, которая используется конструктором для загрузки файла данных (load
также может быть вызван явно вне конструктора).
Я столкнулся с неожиданной проблемой: функция load
, вызываемая конструктором, обрабатывает класс как тип Base
, но когда я использую конструктор по умолчанию и вызываю функцию load
явно,затем таблица виртуальных функций позволяет вызывать намеченную функцию load
.
Это пахнет как классическая проблема, но я не могу придумать, как это сделать (и я совсем недавно программировал на Python, который, я считаю, из-за слабой типизации всегда вызывал бы намеченную функцию).
В том же духе я бы очень хотел, чтобы Base::load
был чисто виртуальным / абстрактным (будут создаваться только производные классы);однако, это не скомпилируется (я полагаю, потому что компилятор видит, что будет вызываться чисто виртуальная функция).
Вы можете помочь?
Вывод:
Загрузка с конструктором:
База :: загрузить файл_A
База :: загрузить файл_B Загрузка с функцией пост-строительства:
Derived_A :: загрузить файл_A
Derived_B ::загрузить файл_B
код:
#include <iostream>
#include <string>
class Base
{
public:
Base() {}
Base(std::string x)
{
load(x);
}
virtual void load(std::string x)
{
std::cout << "\tBase::load " << x << std::endl;
}
};
class Derived_A : public Base
{
public:
Derived_A() {}
Derived_A(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_A::load " << x << std::endl;
}
};
class Derived_B : public Base
{
public:
Derived_B() {}
Derived_B(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_B::load " << x << std::endl;
}
};
int main()
{
// simpler code, but it doesn't behave as I hoped
std::cout << "Loading w/ constructor:" << std::endl;
Base*der_a = new Derived_A(std::string("file_A"));
Base*der_b = new Derived_B(std::string("file_B"));
// this is what I want to do
std::cout << "Loading w/ function post construction:" << std::endl;
der_a = new Derived_A;
der_a->load( std::string("file_A") );
der_b = new Derived_B;
der_b->load( std::string("file_B") );
return 0;
}