以下测试代码的目标是使用优先级队列根据优先级排序任务。
该计划的预期输出为: 4 3 2 1
但是程序给了我结果: 1 3 3 3
问题1: 我可以理解,通过 param 引用传递的'prio'值已被复制构造函数和复制赋值运算符覆盖,但我不知道如何避免它。 / p>
问题2: 为什么编译器明确要求定义复制构造函数和复制赋值运算符,即使我没有在构造函数中分配任何内存?
#include<iostream>
#include<queue>
#include<vector>
#include <algorithm>
template<typename T, typename Param>
class Task
{
public:
typedef void (T::*Func)(Param&);
T* object;
Func func;
Param& param;
int priority;
Task(T& obj_, Func f_, Param& p_, int pp)
:object(&obj_), func(f_), param(p_),priority(pp) { }
virtual ~Task() {}
virtual void operator()() const { (object->*func)(param); }
// WHY I NEED COPY CONSTRUCTOR AND COPY ASSIGNMENT ???
// Copy Constructor -- Not sure... I need to allocate new memory ??
Task(const Task& obj)
:object(obj.object), func(obj.func), param(obj.param),priority(obj.priority)
{
}
// Copy Assignment Operator
Task& operator=(const Task obj){
object= obj.object; func = obj.func; param = obj.param;
priority = obj.priority;
return *this;
}
};
//谓词:最高优先级任务应位于队列的顶部
struct TaskCompare
{
template<typename T, typename Param>
bool operator()(const Task< T,Param > &t1, const Task< T,Param > &t2) const
{
return t1.priority < t2.priority;
}
};
template<typename T, typename Param>
class taskQ
{
public:
std::priority_queue<Task< T,Param >, std::vector<Task< T,Param > >,
TaskCompare> queue;
void addTask(T& t, void (T::*f)(Param&), Param& p_, int pri) {
queue.push(Task< T,Param >( t, f, p_, pri));
}
void executeTask() {
while(!queue.empty()) {
queue.top()();
queue.pop();
}
}
};
typedef struct Param_t {
int prio;
}Param_t;
class Core {
public:
Core() {}
void print(Param_t& p) { std::cout<<p.prio;
}
};
int main(int argc, char ** argv) {
taskQ<Core,Param_t&> t;
Core *c = new Core();
Param_t param;
param.prio= 3;
t.addTask(*c,&Core::print, param,param.prio);
Param_t param1;
param1.prio= 1;
t.addTask(*c,&Core::print, param1,param1.prio);
Param_t param2;
param2.prio= 2;
t.addTask(*c,&Core::print, param2,param2.prio);
Param_t param3;
param3.prio = 4;
t.addTask(*c,&Core::print, param3,param3.prio);
t.executeTask();
return 0;
}
答案 0 :(得分:0)
你的问题已经通过按值而不是通过引用来解决:
#include<iostream>
#include<queue>
#include<vector>
#include <algorithm>
template<typename T, typename Param>
class Task
{
public:
typedef void (T::*Func)(Param);
T* object;
Func func;
Param param;
int priority;
Task(T& obj_, Func f_, Param p_, int pp)
:object(&obj_), func(f_), param(p_),priority(pp) { }
virtual ~Task() {}
virtual void operator()() const { (object->*func)(param); }
// WHY I NEED COPY CONSTRUCTOR AND COPY ASSIGNMENT ???
// Copy Constructor -- Not sure... I need to allocate new memory ??
Task(const Task& obj)
:object(obj.object), func(obj.func), param(obj.param),priority(obj.priority)
{
}
// Copy Assignment Operator
Task& operator=(const Task obj){
object= obj.object; func = obj.func; param = obj.param;
priority = obj.priority;
return *this;
}
};
struct TaskCompare
{
template<typename T, typename Param>
bool operator()(const Task< T,Param > &t1, const Task< T,Param > &t2) const
{
return t1.priority < t2.priority;
}
};
template<typename T, typename Param>
class taskQ
{
public:
std::priority_queue<Task< T,Param >, std::vector<Task< T,Param > >,
TaskCompare> queue;
void addTask(T& t, void (T::*f)(Param), Param p_, int pri) {
queue.push(Task< T,Param >( t, f, p_, pri));
}
void executeTask() {
while( !queue.empty()) {
queue.top()();
queue.pop();
}
}
};
typedef struct Param_t {
int prio;
}Param_t;
class Core {
public:
Core() {}
void print(Param_t p) { std::cout<<p.prio;}
};
用法:
int main(int argc, char ** argv) {
taskQ<Core,Param_t> t;
Core *c = new Core();
Param_t param;
param.prio= 3;
t.addTask(*c,&Core::print, param,param.prio);
Param_t param1;
param1.prio= 1;
t.addTask(*c,&Core::print, param1,param1.prio);
Param_t param2;
param2.prio= 2;
t.addTask(*c,&Core::print, param2,param2.prio);
Param_t param3;
param3.prio = 4;
t.addTask(*c,&Core::print, param3,param3.prio);
t.executeTask();
return 0;
}
打印:
4321 运行成功(总时间:73毫秒)