2017-09-13 49 views
-3

我有這樣的當前設置所謂的禁忌:C++使用的拷貝構造函數是由PriorityQueue中

#include <iostream> 
#include <queue> 
#include <vector> 
class A 
    { 
     int val; 
    public: 
     A() 
     { 
      std::cout << "Inside A. Constructor with val =" << val << ".\n"; 
     } 
     A(const A& msg) 
     { 
      std::cout << "Inside const A. Never want to come here. val =" << msg.val << ".\n"; 
     } 
     bool operator()(const A* m1, const A* m2) 
     { 
      std::cout << "Inside() function.\n"; 
      std::cout << "m1: " << m1->GetVal() << " m2: " << m2->GetVal()<<"\n"; 
      return (m1->GetVal() < m2->GetVal()); 
     } 
     void setVal(int input) { std::cout << "inside setVal.\n"; val = input; } 
     int GetVal()const { return val; } 

    }; 


    void specialPriorityQueue() 
    { 
     //init 
     A* val = new A(); 
     val->setVal(5); 
     std::priority_queue<A*, std::vector<A*>, A> pq; 
     pq.push(val); 

     A* val2 = new A(); 
     val2->setVal(3); 
     pq.push(val2); 

     delete val; 
     delete val2; 
    } 
int main() 
    { 
     specialPriorityQueue(); 
return 0; 
    } 

輸出:

Inside A. Constructor with val =-85000000... 
inside setVal. 
Inside A. Constructor with val =-85000000... 
Inside const A. Never want to come here. val =-85000000.... 
Inside A. Constructor with val =-85000000... 
inside setVal. 
Inside const A. Never want to come here. val =-85000000.... 
Inside() function. 
m1: 5 m2: 3 

我的問題是:有沒有辦法避免使用拷貝構造函數優先隊列。這會導致未定義的行爲。我無法刪除該功能,因爲它在別處有太多的依賴關係。

+7

如果您的複製構造函數導致UB,請修復它。 – juanchopanza

+0

@juanchopanza在這種情況下它不。 –

+0

您是否考慮過刪除複製構造函數並使用'A(const A&)= delete'和'A&operator =(const A&)= delete;'複製賦值運算符? –

回答

1

該複製構造函數在創建比較對象時調用,該對象也是您的元素類型A

使用另一種類型的比較,如:

struct Compare 
{ 
    bool operator()(const A* m1, const A* m2) const { 
     return m1->GetVal() < m2->GetVal(); 
    } 
}; 

然後:

std::priority_queue<A*, std::vector<A*>, Compare> pq; 

而且,甚至更好,使用智能指針,以避免內存泄漏:

struct Compare 
{ 
    bool operator()(std::unique_ptr<A> const& m1, std::unique_ptr<A> const& m2) const { 
     return m1->GetVal() < m2->GetVal(); 
    } 
}; 

void specialPriorityQueue() { 
    std::unique_ptr<A> val(new A()); 
    val->setVal(5); 
    std::priority_queue<std::unique_ptr<A>, std::vector<std::unique_ptr<A>>, Compare> pq; 
    pq.push(move(val)); 

    std::unique_ptr<A> val2(new A()); 
    val2->setVal(3); 
    pq.push(move(val2)); 
}