Цель следующего тестового кода - упорядочить задачи в соответствии с их приоритетом с использованием очереди приоритетов.
Ожидаемый результат программы: 4 3 2 1
Но программа дает мне результат: 1 3 3 3
Проблема 1. Я могу понять, что значение "prio", которое передается посредством ссылки через параметр, перезаписывается конструктором копирования и оператором присваивания копии, но я не знаю, как его избежать.
Проблема 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;
}
ваша проблема решена путем принятия аргументов по значению, а не по ссылке:
#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 RUN УСПЕШНОЕ (общее время: 73 мс)
param
вместо копии? Это выглядит как основная причина ваших трудностей (необходимость в конструкторе копирования и перезаписи значений)