关于C ++中方法覆盖的this文章中的维基百科示例是否正确?
请参阅下面的代码,我在其中提到了评论// INCORRECT
稍微混淆了C ++和运行时多态性。这个演员应该怎么做?
#include <iostream>
class Rectangle {
public:
explicit Rectangle(double l, double w) : length(l), width(w) {}
virtual void print() const;
private:
double length;
double width;
};
void Rectangle::print() const { // print() method of base class
std::cout << "Length = " << this->length << "; Width = " << this->width;
}
class Box : public Rectangle {
public:
explicit Box(double l, double w, double h) : Rectangle(l, w), height(h) {}
virtual void print() const; // virtual is optional here, but it is a good practice to remind it to the developer
private:
double height;
};
void Box::print() const { // print() method of derived class
Rectangle::print(); // Invoke parent print() method.
std::cout << "; Height= " << this->height;
}
int main(int argc, char** argv) {
Rectangle rectangle(5.0, 3.0); rectangle.print();
// outputs:
// Length = 5.0; Width = 3.0
Box box(6.0, 5.0, 4.0);
// the pointer to the most overridden method in the vtable in on Box::print
//box.print(); // but this call does not illustrate overriding
static_cast<Rectangle&>(box).print(); // this one does
// outputs:
// Length = 5.0; Width = 3.0; Height= 4 // INCORRECT
//But it actually outputs Length = 6; Width = 5; Height = 4
getchar();
return 0;
}
答案 0 :(得分:3)
你是对的 - 提到的输出不正确。
演员表只是演示了一个框是一种矩形(从它继承),即使是一个矩形,方法覆盖仍然有效,Box
方法的print
版本将被召唤。
答案 1 :(得分:3)
随意修复维基百科中的评论:输出应该是Length = 6; Width = 5; Height = 4
。
另一部分是正确的:即使在Box.print()
引用被静态转换为对其超类的引用之后调用Box
的代码确实证明了如何覆盖虚方法适用于C ++。
证明同一点的另一种方法是使用指针而不是引用:
Rectangle *boxPtr = &box;
boxPtr->print();
答案 2 :(得分:2)
文章中的评论确实是错误的(现在已经修复);你应该打印6,5和4。
强制转换的目的是证明,即使你通过对基类(Rectangle
)的引用来调用虚函数,它也会调用与对象的实际类型相关联的覆盖({ {1}}) - 您仍然可以获得Box
打印的三个值,而不是Box::print()
打印的两个值。
答案 3 :(得分:2)
这一行:static_cast<Rectangle&>(box).print();
与此代码具有相同的效果:
Rectangle & r = box;
r.print();
也与此代码具有相同的效果:
Rectangle * r = &box;
r->print();
这意味着Box对象已创建(Box box(6.0, 5.0, 4.0);
=在运行时,您看到Box
)并且存储此对象的指针/引用的类型无关紧要。您将框存储为Rectangle*
这一事实就是您在编译时看到的。
关于覆盖虚拟方法的最重要的事实是关于“将调用哪个方法?”在运行时决定。
希望这有帮助。