我有一个名为Shape的抽象基类,从中派生出Circle和Rectangle,但是当我在VS 2005中执行以下代码时,我得到错误Debug assertion failed。与此同时,我没有在任何类中重载==运算符
表达式:向量迭代器不可解除引用,原因是什么。
vector<Shape*> s1;
s1.push_back(new Circle(point(1,2),3));
s1.push_back(new Circle(point(4,3),5));
s1.push_back(new Rectangle(point(1,1),4,5));
vector<Shape*> s2(s1);
reverse(s1.begin(),s1.end());
(*find(s1.begin(),s1.end(),new Circle(point(1,2),3)))->move(point(10,20));
答案 0 :(得分:12)
简单:
为了让它按你想要的方式工作,你需要比较Shape,而不是Shape *
正如其他答案中所指出的,boost::ptr_vector是实现这一目标的简单方法。
答案 1 :(得分:6)
像@David Pierre建议的那样:find是基于值的:它在指针的迭代器范围内查找(例如0x0F234420),它等于指向刚刚创建的new Circle(point(1,2),3)
的指针。由于这是一个新对象,它不会存在。
你可以使用find_if
和一个比较指针引用的对象的运算符来解决这个问题。
然而,Criterium应该能够区分形状类型。
class Shape {
public:
//amongst other functions
virtual bool equal( const Shape* ) const = 0;
};
class Circle : public Shape {
public:
bool equal( const Shape* pOther ) const {
const Circle* pOtherCircle = dynamic_cast<const Circle*>( pOther );
if( pOtherCircle == NULL ) return false;
// compare circle members
}
};
class Rectangle : public Shape {
public:
bool equal( const Shape* pOther ) const {
const Rectangle* pOtherR = dynamic_cast<const Rectangle*>( pOther );
if( pOtherR == NULL ) return false;
// compare rectangle members
}
};
Shape* pFindThis = new Circle(point(1,2),3);
vector<Shape*>::const_iterator itFound = find_if(s1.begin(),s1.end(),
bind1st( mem_fun( &Shape::equal ), pFindThis) ) );
delete pFindThis; //leak resolved by Mark Ransom - tx!
if( itFound != s1.end() ) {
(*itFound)->move(point(10,20));
}
答案 2 :(得分:2)
这是使用boost :: ptr_vector的一个很好的理由。
它不仅可以处理您的物品需要被摧毁的事实 xtofl @:你忘记了虚拟析构函数。
但它也通过返回引用而不是指针使成员看起来像对象。这允许您更自然地使用标准算法,而不是在“相等”函数中使用指针(这非常类似于C ++)。
#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
class Shape
{
public:
~Shape() {}
bool operator==(Shape const& rhs) const
{
if (typeid(*this) != typeid(rhs))
{
return false;
}
return this->isEqual(rhs);
}
private:
virtual bool isEqual(Shape const& rhs) const = 0;
};
class Circle: public Shape
{
public:
Circle(int r)
:radius(r)
{}
private:
virtual bool isEqual(Shape const& r) const
{
Circle const& rhs = dynamic_cast<Circle const&>(r);
return radius == rhs.radius;
}
int radius;
};
class Rectangle: public Shape
{
public:
Rectangle(int h,int w)
:height(h)
,width(w)
{}
private:
virtual bool isEqual(Shape const& r) const
{
Rectangle const& rhs = dynamic_cast<Rectangle const&>(r);
return (height == rhs.height) && (width == rhs.width);
}
int height;
int width;
};
int main()
{
boost::ptr_vector<Shape> data;
data.push_back(new Circle(5));
data.push_back(new Circle(6));
data.push_back(new Rectangle(7,4));
boost::ptr_vector<Shape>::iterator f;
f = find(data.begin(),data.end(),Circle(6));
std::cout << "Find(" << (f - data.begin() ) << ")" << std::endl;
}