[英]C++ Boost Priority Queue Behavior
I tried to find out exactly how the boost priority queue is implemented and I am confused.我试图弄清楚提升优先级队列是如何实现的,我很困惑。
Header file (main.hpp): Header 文件(main.hpp):
#ifndef MAIN_HPP
#define MAIN_HPP
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <boost/heap/priority_queue.hpp>
typedef std::int32_t int32_t;
typedef struct st {
int32_t num;
int32_t f;
st() {
std::cout << "DEFAULT" << std::endl;
this->f = 0;
}
st(int32_t num) {
std::cout << "creation\t" << num << std::endl;
this->num = num;
this->f = 0;
}
~st() {
std::cout << "del\t" << num << std::endl;
f = 1;
}
} st;
typedef struct st_c0 {
bool operator()(const st& st0, const st& st1) const {
return (st0.num > st1.num);
}
} st_c0;
typedef struct st_c1 {
bool operator()(const st* st0, const st* st1) const {
return (st0->num > st1->num);
}
} st_c1;
#endif
#include "main.hpp"
int main() {
boost::heap::priority_queue<st, boost::heap::compare<st_c0>> q0;
boost::heap::priority_queue<st*, boost::heap::compare<st_c1>> q1;
st y = st(5);
q0.push(st(44));
q0.push(y);
q0.empty();
std::cout << y.f << std::endl;
return 0;
}
The output I get is:我得到的 output 是:
creation 5
creation 44
del 44
del 44
del 44
del 44
del 44
del 5
del 5
del 5
0
del 5
del 5
del 44
The order of object creation and deletion does not make sense. object 创建和删除的顺序没有意义。 How do the internals of the priority queue work, and what is the best practice for them (storing pointers vs storing objects)?优先级队列的内部是如何工作的,它们的最佳实践是什么(存储指针与存储对象)?
You aren't accounting for the copy-constructor that will automatically be created for your class.您没有考虑将为您的 class 自动创建的复制构造函数。
In your case you wouldn't automatically get a move-constructor, but it's still nice to see where the compiler could do a move instead of a copy.在您的情况下,您不会自动获得移动构造函数,但是很高兴看到编译器可以在哪里进行移动而不是复制。
If you change your st
to eg:如果您将st
更改为例如:
struct st {
int32_t num;
int32_t f;
st() {
std::cout << this << "\tctor default" << std::endl;
this->f = 0;
}
st(int32_t num) : num(num), f(0) {
std::cout << this << "\tctor num\t" << num << std::endl;
}
st(st const& other) : num(other.num), f(other.f) {
std::cout << this << "\tctor copy\t" << num << "\t (from " << &other << ")" << std::endl;
}
st(st&& other): num(other.num), f(other.f) {
std::cout << this << "\tctor move\t" << num << "\t (from " << &other << ")" << std::endl;
}
st& operator=(st const& other) {
num = other.num;
f = other.f;
std::cout << this << "\tassign copy\t" << num << "\t (from " << &other << ")" << std::endl;
return *this;
}
st& operator=(st&& other) {
num = other.num;
f = other.f;
std::cout << this << "\tassign move\t" << num << "\t (from " << &other << ")" << std::endl;
return *this;
}
~st() {
std::cout << this << "\tdtor\t\t" << num << std::endl;
}
};
you'll get a better picture of what's going on:你会更好地了解正在发生的事情:
// construct y
0x7fffd8f3b1e8 ctor num 5
// call to push(st(44))
0x7fffd8f3b238 ctor num 44
0x7fffd8f3b1b4 ctor copy 44 (from 0x7fffd8f3b238)
0x97cec0 ctor move 44 (from 0x7fffd8f3b1b4)
0x7fffd8f3b1b4 dtor 44
0x7fffd8f3b164 ctor move 44 (from 0x97cec0)
0x7fffd8f3b178 ctor move 44 (from 0x7fffd8f3b164)
0x97cec0 assign move 44 (from 0x7fffd8f3b178)
0x7fffd8f3b178 dtor 44
0x7fffd8f3b164 dtor 44
0x7fffd8f3b238 dtor 44
// call to push(y)
0x7fffd8f3b1b4 ctor copy 5 (from 0x7fffd8f3b1e8)
0x97cee8 ctor move 5 (from 0x7fffd8f3b1b4)
0x97cee0 ctor copy 44 (from 0x97cec0)
0x97cec0 dtor 44
0x7fffd8f3b1b4 dtor 5
0x7fffd8f3b164 ctor move 5 (from 0x97cee8)
0x7fffd8f3b178 ctor move 5 (from 0x7fffd8f3b164)
0x97cee8 assign move 44 (from 0x97cee0)
0x97cee0 assign move 5 (from 0x7fffd8f3b178)
0x7fffd8f3b178 dtor 5
0x7fffd8f3b164 dtor 5
// after main()
0x7fffd8f3b1e8 dtor 5
0x97cee0 dtor 5
0x97cee8 dtor 44
So to break it down:所以分解它:
st
is constructed and after that copied & moved a few times.您的st
已构建,然后复制并移动了几次。0x97cec0
(the allocated storage from the heap)它最终以0x97cec0
结束(从堆中分配的存储)empty()
clear()
.如果要删除所有元素,请使用clear()
。st
's优先级队列被破坏并为两个st
调用析构函数There are no guarantees though how many copies / moves the implementation of boost::heap::priority_queue<st, boost::heap::compare<st_c0>>
does, so this might change at any time.尽管boost::heap::priority_queue<st, boost::heap::compare<st_c0>>
的实现没有保证多少副本/移动,所以这可能随时改变。
In general you would use objects whenever they are small and easy to copy / move.通常,只要对象很小且易于复制/移动,您就会使用它们。
If you use pointers your object won't be copied or moved at all, only the pointer to it, so this would be better if your objects are large and / or expensive to copy / move.如果您使用指针,您的 object 根本不会被复制或移动,只有指向它的指针,所以如果您的对象很大和/或复制/移动成本很高,这会更好。
But with bare pointers you also need to delete
them manually, if possible i would recommend to use smart pointers instead, eg:但是对于裸指针,您还需要手动delete
它们,如果可能的话,我建议使用智能指针,例如:
boost::heap::priority_queue<boost::shared_ptr<st>, boost::heap::compare<TODO>> q0;
that way your ``st`'s autmatically get freed & you don't have to manually delete them.这样你的“st”就会自动被释放,你不必手动删除它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.