我确信代码是非常自我解释的,所以我直截了当地说。如果代码不清楚,请询问更多详细信息。
Foo.h
=====
#include <iostream>
class Foo
{
public:
virtual ~Foo(){};
Foo();
Foo(const int b);
bool operator<(const Foo&) const;
friend std::ostream& operator<<(std::ostream&, const Foo&);
int b;
};
Foo.cpp
=======
#include "Foo.h"
Foo::Foo()
{
}
Foo::Foo(const int b)
{
this->b = b;
}
bool Foo::operator<(const Foo& other) const
{
return b < other.b;
}
std::ostream& operator<<(std::ostream& os, const Foo& f)
{
os << '{' << f.b << '}';
return os;
}
Bar.h
=====
#include <vector>
#include <queue>
#include "Foo.h"
class Bar
{
struct FooPp
{
Foo f;
int a;
FooPp(const Foo&);
bool operator<(const FooPp&) const;
friend std::ostream& operator<<(std::ostream& os, const FooPp& fpp)
{
os << '[' << fpp.a << "]," << fpp.f;
return os;
}
};
struct foopp_compare
{
bool operator()(const FooPp* pA, const FooPp* pB ) const
{
return *pA < *pB;
}
};
public:
virtual ~Bar(){};
Bar(const std::vector<Foo>&);
std::vector<FooPp> vf;
std::priority_queue<FooPp*, std::vector<FooPp*>, foopp_compare> fq;
};
Bar.cpp
=======
#include "Bar.h"
Bar::FooPp::FooPp(const Foo& f)
{
this->f = f;
a = f.b;
}
bool Bar::FooPp::operator<(const FooPp& other) const
{
return f < other.f;
}
Bar::Bar(const std::vector<Foo>& vf)
{
for (std::vector<Foo>::const_iterator f = vf.begin();
f != vf.end();
++f)
{
this->vf.push_back(*f);
fq.push(&(this->vf.back()));
}
}
main.cpp
========
#include <iostream>
#include "Bar.h"
int main()
{
// Foo
Foo f1(1);
Foo f2(6);
std::vector<Foo> vf;
vf.push_back(f1);
vf.push_back(f2);
// Bar
Bar b(vf);
// print b.vf: [1]{1}, [6],{6};
std::cout << b.vf[0] << '\n';
std::cout << b.vf[1] << '\n';
// print the top of the prio_q: [6],{6};
std::cout << *(b.fq.top()) << '\n';
// change "a" in b.vf[1] -> [-12],{6}
b.vf[1].a = -12;
// print b.vf[1]: [-12],{6};
std::cout << b.vf[1] << '\n';
// print the top of the prio_q: [-12],{6};
std::cout << *(b.fq.top()) << '\n';
return 0;
}
这就是我所得到的:
./example
[1],{1} // OK
[6],{6} // OK
[1],{135704652} // ??
[-12],{6} // OK
[1],{135704652} // ??
std::vector<FooPp>
似乎已正确初始化,但我不明白std::priority_queue
发生了什么,应该使用指向std::vector<FooPp>
元素的指针进行初始化。怎么了?
顺便说一句..这是Unix机器上那些人的makefile
Makefile
========
CXX := g++
LD := g++
CXXFLAGS := -Wall -g -O0 --std=c++0x -I.
SRC := $(shell ls *.cpp)
OBJ := ${SRC:%.cpp=%.o}
.PHONY: clean
example: $(OBJ)
$(LD) $^ -o $@
clean:
rm -rf $(OBJ) *~ example
答案 0 :(得分:2)
每次推送都会修改基础向量vf
,并使进程中的所有迭代器(以及从中获取的地址)无效。
我看到解决此问题的最快方法是修改Bar
的构造函数:
Bar::Bar(const std::vector<Foo>& vf)
: vf(vf.begin(), vf.end())
{
for (std::vector<FooPp>::iterator f = this->vf.begin();
f != this->vf.end();
++f)
{
fq.push(&(*f));
}
}
<强>输出强>
[1],{1}
[6],{6}
[6],{6}
[-12],{6}
[-12],{6}
还有一个主机我将对此代码做的其他事情(使用初始化程序列表等),但这是关于我能想到的最小的代码更改将为您提供一些的工作原理。
答案 1 :(得分:0)
我认为问题出在这里
Bar::Bar(const std::vector<Foo>& vf)
{
for (std::vector<Foo>::const_iterator f = vf.begin();
f != vf.end();
++f)
{
this->vf.push_back(*f);
fq.push(&(this->vf.back()));
}
}
向向量添加新元素时,可以重新分配已用内存。所以这个值&amp;(this-&gt; vf.back())变得无效。