我正在尝试构建一个类型取决于输入参数的对象。例如,我的对象被称为“进程”,并且在运行时输入了一个介于 2 和 5(含)之间的整数,并且会发生类似这样的事情:
if (input == 2) TwoJ process;
if (input == 3) ThreeJ process;
if (input == 4) FourJ process;
if (input == 5) FiveJ process;
显然上述方法不起作用,因为对象立即超出范围。有没有办法很好地实现这一点?干杯
使用一个工厂函数,它返回一个指向基类的智能指针Process,其实现由提供给工厂函数的整数值确定(要求所有类都有一个共同的基类)。
例如:
class Base_process
{
public:
virtual ~Base_process() {}
virtual void do_something() = 0;
};
class TwoJ : public Base_process
{
public:
void do_something() {}
}
class ThreeJ : public Base_process
{
public:
void do_something() {}
}
std::unique_ptr<Base_process> make_process(int a_type)
{
if (a_type == 1) return std::unique_ptr<Base_process>(new TwoJ());
if (a_type == 2) return std::unique_ptr<Base_process>(new ThreeJ());
// Report invalid type or return an acceptable default if one exists.
throw std::invalid_argument("Unknown type:" + std::to_string(a_type));
}
一种工厂方法
std::unique_ptr<ProcessType> CreateProcess(int input){
if(input == 2) return std::unique_ptr<ProcessType>(new TwoJ());
.....
}
当然,这假设您使用的各种类都有一个公共基类 here ProcessType,并且您对通过基类指针与它进行交互感到满意。
你可以但是,你需要1个基类,例如
Base* process;
if (input == 2) process = new TwoJ();
if (input == 3) process = new ThreeJ();
那么要访问这些类,您只需要:
if (input == 2) (TwoJ*)process->someTwoJMethod();
或使用 dynamic_cast:
TwoJ* p = dynamic_cast<TwoJ*>(process);
if(p != 0) {
p->someTwoJMethod();
}
有了这个,一旦超出范围,您就有责任删除您的对象。以前的答案是 cpp 中使用std::unique_ptr该对象的最佳方式,当对象超出范围时会自动删除。