2017-09-13 3 views
-3

J'ai cette configuration actuelle:C++ Éviter l'utilisation constructeur de copie qui est appelée par 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; 
    } 

sorties:

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 

Ma question est: Est-il possible d'éviter d'utiliser le constructeur de copie par la file d'attente prioritaire. Cela provoque un comportement indéfini. Je ne peux pas enlever la fonction non plus car elle a trop de dépendances ailleurs.

+7

Si votre constructeur de copie provoque UB, corrigez-le. – juanchopanza

+0

@juanchopanza Dans ce cas, ce n'est pas le cas. –

+0

Avez-vous envisagé de supprimer le constructeur de copie et les opérateurs d'affectation de copie avec 'A (const A &) = delete' et' A & operator = (const A &) = delete; '? –

Répondre

1

Ce constructeur de copie est appelé lorsqu'il crée l'objet comparateur, qui est également le type de votre élément, A.

Utilisez un autre type de comparaison, par exemple:

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

Et puis:

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

Et, mieux encore, utiliser des pointeurs intelligents pour éviter les fuites de mémoire:

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)); 
}