我的目标是填写一份任务清单;每个都是一个包含任务描述的对象。我们将只有两种类型的任务:文件复制和剧目复制。
由于向量不能包含多种类型的对象,我可以创建一个通用的任务类和两个继承该类的对象。
以下是代码:
#include <iostream>
#include <deque>
#include <string>
using namespace std;
class GenericTask{
public :
string config;
GenericTask(string s){
config=s;
}
void run(){
cout<<"Running generic task" <<endl;
}
};
class FileCopyTask : public GenericTask{
public:
string filename;
FileCopyTask(string cf,string fn):GenericTask(cf)
{
filename=fn;
}
void run(){
cout<<"file :"<<filename<<endl;
}
};
class RepertoryCopyTask : public GenericTask{
public:
string repname;
RepertoryCopyTask(string cf,string rn):GenericTask(cf)
{
repname=rn;
}
void run(){
cout<<"repertory : "<<repname<<endl;
}
};
void run_next(deque<GenericTask> &task_list){
task_list.front().run();
task_list.pop_front();
}
int main()
{
RepertoryCopyTask rtask("configuration","/home");
FileCopyTask ftask( "configutation","gile.tex" );
deque<GenericTask> task_list;
task_list.push_back(rtask);
task_list.push_back(ftask);
run_next(task_list);
}
因为它不起作用,因为run_next
期望GenericTask
,rtask
和ftask
都被视为通用。
我该怎么办?
我已经尝试在这里和那里添加template
,但最终它不起作用,因为我需要知道deque
中的类型才能“提取”某些内容。
我可以将this视为答案吗?
答案 0 :(得分:1)
为什么不创建FileCopyTask
和RepertoryCopyTask
的对象并将其保存为GenericTask
的指针?这样,您就可以利用运行时多态性的强大功能。
像这样:
int main()
{
std::unique_ptr<GenericTask> ftask = std::make_unique<FileCopyTask>("configutation","gile.tex");
std::unique_ptr<GenericTask> rtask = std::make_unique<FileCopyTask>("configuration","/home");
...
}
void run_next(deque<std::unique_ptr<GenericTask> > &task_list)
{
....
}
另外,不要忘记将班级run()
中的GenericTask
方法标记为virtual
。还提供virtual
析构函数。
答案 1 :(得分:1)
我在你的来源做了一些改变。使用指针将基本fn定义为虚拟和存储对象。你可以在下面查看。
#include <iostream>
#include <deque>
#include <string>
using namespace std;
class GenericTask{
public :
string config;
GenericTask(string s){
config=s;
}
virtual void run(){
cout<<"Running generic task" <<endl;
}
};
class FileCopyTask : public GenericTask{
public:
string filename;
FileCopyTask(string cf,string fn):GenericTask(cf)
{
filename=fn;
}
void run(){
cout<<"file :"<<filename<<endl;
}
};
class RepertoryCopyTask : public GenericTask{
public:
string repname;
RepertoryCopyTask(string cf,string rn):GenericTask(cf)
{
repname=rn;
}
void run(){
cout<<"repertory : "<<repname<<endl;
}
};
void run_next(deque<GenericTask*> &task_list){
task_list.front()->run();
task_list.pop_front();
}
int main()
{
RepertoryCopyTask* rtask = new RepertoryCopyTask("configuration","/home");
FileCopyTask* ftask = new FileCopyTask( "configutation","gile.tex" );
deque<GenericTask*> task_list;
task_list.push_back(ftask);
task_list.push_back(rtask);
run_next(task_list);
}
答案 2 :(得分:0)
我该怎么办?
请考虑以下步骤:
void run
virtual)我已经尝试过在这里和那里添加模板,但最终它不起作用,因为我需要知道deque中的类型才能“提取”某些内容。
您可以添加boost :: variant作为值,允许存储不相关的类型。
我可以考虑这个[这个=答案提出boost :: any作为值类型]作为答案吗?
是。 boost :: variant类似(不同之处在于boost :: any支持设置任何值; boost :: variant仅支持作为variant参数提供的类型的值)。
答案 3 :(得分:-1)
virtual
的经典案例。 run方法需要声明为virtual
s.t.你实际上是在GenericTask类型的对象上调用RepertoryCopyTask :: run()。
正确完成后,
FileCopyTask t("a", "b");
GenericTask & g = t;
g.run();
会拨打FileCopyTask::run
而不是GenericTask::run
(原始问题中会这样)。
执行此操作时,您无法将FileCopyTask
和RepertoryCopyTask
存储在GenericTask
的容器中。这是因为它们甚至可能具有不同的尺寸。要解决这个问题,您应该将unique_ptr
s存储在某个容器中,即
std::vector<std::unique_ptr<GenericTask> > tasks;
这将是解决问题的正确方法。