根据SGI's doc on associative containers的说法,“由于元素是根据它们的键存储的,因此与每个元素关联的键必须是不可变的”。我有时使用指针作为std::map的键,因为虽然指向的对象可能是可变的,但指针本身是恒定的。
从技术上讲,QPointer是一个模仿指针的对象,Qt's doc说我们可以像使用指针一样使用QPointers。由于QPointer对象本身在执行过程中可能会发生变化,它是否仍然可以用作std::map容器的键?
编辑1:我不能使用QMap,我必须坚持使用std::map。
编辑2:代码在我使用QPointer时编译。问题是我是否应该期待在运行时出现令人不快的惊喜。
发布于 2011-03-09 06:12:30
不,这是不安全的,因为当QObject被销毁时,QPointer可能会更改为NULL。(QPointer类似于std::weak_ptr。)所以这段代码会产生未定义的行为:
class CopyableWidget : public QWidget {
Q_OBJECT;
public:
CopyableWidget(Widget* parent = 0) : QWidget(parent) {}
CopyableWidget(const CopyableWidget& w, Widget* parent = 0) : QWidget(parent) {}
};
std::vector<CopyableWidget> v(2); // Two default-constructed widgets
std::map<QPointer<CopyableWidget>, int> wid_values;
wid_values[&v[0]] = 1;
wid_values[&v[1]] = 2;
// wid_values contains { {&v[0], 1}, {&v[1], 2} }
v.resize(1);
// The QPointer in wid_values constructed from &v[1] now acts like NULL.
// wid_values contains { {&v[0], 1}, {NULL, 2} }
// But &v[0] > NULL (on most platforms). Class invariant was violated!发布于 2011-03-09 05:23:20
我认为(从最小意外原则出发)如果不重新分配QPointer,也不删除底层对象,它就不会“神奇”地改变它所指向的位置,所以它应该是安全的。
(我必须补充的是,我已经多次看到Qt违反了最小惊讶原则,所以一定要测试一下。)
发布于 2011-03-09 05:34:19
比较来自不同分配块的指针以获取除相等/不等之外的任何内容,这是未定义的行为。也就是说,在分配一个带有new或malloc的块之后,你可以遍历缓冲区并测试你的指针是否小于缓冲区的末尾。但是你不能做两个单独的news/mallocs,并且比较除相等/不等之外的任何结果指针。
好吧..。你可以,但你可能不喜欢结果。
https://stackoverflow.com/questions/5238437
复制相似问题