Значение, перезаписанное конструктором копирования в очереди приоритетов

0

Цель следующего тестового кода - упорядочить задачи в соответствии с их приоритетом с использованием очереди приоритетов.

Ожидаемый результат программы: 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;
 }
  • 0
    код не скомпилируется, не добавит const к operator () и не изменится, пока условие в executeTask ()
  • 0
    Почему вы сохраняете ссылку на param вместо копии? Это выглядит как основная причина ваших трудностей (необходимость в конструкторе копирования и перезаписи значений)
Показать ещё 1 комментарий
Теги:
algorithm
reference
stl
copy-constructor

1 ответ

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 мс)

  • 0
    Для экономии памяти / времени я передаю «param» по ссылке (пожалуйста, учтите, что «param» имеет много элементов данных) или это одно из моих требований. Передавая по значению метод, я уже следовал, передавая «param.prio» - это не моя проблема. Большое спасибо, и я очень ценю ваше время и усилия.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню