由优先级队列中的复制构造函数覆盖的值

时间:2014-01-30 11:40:48

标签: c++ algorithm stl reference copy-constructor

以下测试代码的目标是使用优先级队列根据优先级排序任务。

该计划的预期输出为: 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;
 }

1 个答案:

答案 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毫秒)