[英]BOOST and C++: can't seem to get polymorphism to work
I'm using ptr_vector to store "shapes". 我正在使用ptr_vector来存储“形状”。 I'm trying to fill it with derived shape classes, such as "circles", and every time I try to downcast them I get bad cast.
我试图用派生的形状类(例如“圆”)填充它,并且每次我尝试将它们压低时,我都会感到不舒服。
class Shape
{
public:
virtual ~Shape() {};
virtual void print() { std::cout << "shape" << std::endl; };
};
class Circle :
public Shape
{
public:
void print() { std::cout << "circle" << std::endl; };
};
int main()
{
boost::ptr_vector<Shape> shapes;
shapes.push_back(new Circle);
BOOST_FOREACH(Shape shape, shapes)
{
Circle& tempCircle = dynamic_cast<Circle&>(shape);
if(&tempCircle != NULL)
tempCircle.print();
}
system("PAUSE");
}
The problem is that your shape
is an object whose type is Shape
, and not a reference to an object whose (dynamic) type is Circle
. 问题在于您的
shape
是类型为Shape
的对象,而不是对(动态)类型为Circle
的对象的引用。
Polymorphism only works with references or pointers . 多态只适用于引用或指针 。 When treating objects as values and copy-construct or move-construct objects of a base class from objects of a derived class, what you get is slicing (definitely not something you want).
将对象视为值并从派生类的对象中复制基类的对象时,所得到的就是切片 (绝对不是您想要的)。
Try this instead: 尝试以下方法:
BOOST_FOREACH(Shape& shape, shapes)
// ^
It would also make sense to use a reference to const
, probably - since you are not going to modify the referenced object inside the loop, so: 使用对
const
的引用可能也很有意义-因为您不会在循环内修改引用的对象,所以:
BOOST_FOREACH(Shape const& shape, shapes)
// ^^^^^^
{
Circle const& tempCircle = dynamic_cast<Circle const&>(shape);
// ^^^^^^ ^^^^^^
// ...
}
Also notice, that C++11 has range-based for
loops, which make BOOST_FOREACH
kind of obsolete. 还要注意,C ++ 11具有基于范围的
for
循环,这使BOOST_FOREACH
有点过时了。 So if C++11 is an option, you could write: 因此,如果可以选择C ++ 11,则可以编写:
for (auto const& shape : shapes)
{
Circle const& tempCircle = dynamic_cast<Circle const&>(shape);
// ^^^^^^ ^^^^^^
// ...
}
This said, it makes sense to point out ( as Chad does in the comments ) that you do not need to perform a dynamic downcast here, since print()
is a virtual function. 也就是说,有必要指出( 就像Chad在评论中一样 ),因为
print()
是一个虚函数,所以您不需要在此处执行动态向下转换。 When doing: 进行时:
shape.print();
The function call will be dispatched to Circle::print()
if the object referenced by Shape
is an instance of Circle
. 如果
Shape
引用的对象是Circle
的实例,则该函数调用将调度到Circle::print()
。
Also, you're not using dynamic_cast correctly. 另外,您没有正确使用dynamic_cast。 If you dynamic_cast a reference, and the object does not actually belong to the class you're casting it to, then the cast throws
std::bad_cast
. 如果您dynamic_cast一个引用,并且该对象实际上并不属于您要对其进行强制转换的类,则强制转换会抛出
std::bad_cast
。 It does not return null because there's no such thing as a reference with a null address. 它不返回空值,因为不存在带有空地址的引用。 So here's the correct way:
所以这是正确的方法:
Circle* tempCircle = dynamic_cast<Circle*>(&shape);
if(tempCircle != NULL)
tempCircle->print();
(You can actually have a reference r
with &r == NULL
, but only after dereferencing a null pointer, which has undefined behavior.) (实际上,您可以使用
&r == NULL
引用r
,但是只有在取消引用具有未定义行为的空指针之后才可以。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.