动态方法绑定
Dynamic method binding
class Shape {
public:
virtual void draw() = 0;
. . .
};
class Circle : public Shape {
public:
void draw() { . . . }
. . .
};
class Rectangle : public Shape {
public:
void draw() { . . . }
. . .
};
class Square : public Rectangle {
public:
void draw() { . . . }
. . .
};
Rectangle* rect = new Rectangle;
rect->draw(); // Statically bound to the draw in the Rectangle class
在课本中,"concepts of programming language, 10th",
有一部分是关于动态方法绑定的。
我认为rect指向的对象类型不能静态解析,因为rect是多态引用类型。
rect 也可能在 运行 时间内引用 Sqaure 类型对象。
代码上面最后一行不正确??
考虑以下示例
int main
{
Shape* cir = new Circle;
Shape* rec = new Rectangle;
Shape* sqr = new Square;
cir->draw(); // Circle::draw
rec->draw(); // Rectangle::draw
sqr->draw(); // Square::draw
}
所有这些变量cir
、rec
和sqr
都是Shape*
,但由于多态性,它们将调用各自的draw
方法。当我们重新使用同一个变量时,这一点就更清楚了
int main
{
Shape* shape = new Circle;
shape->draw(); // Circle::draw
delete shape;
shape = new Rectangle;
shape->draw(); // Rectangle::draw
delete shape;
shape = new Square;
shape->draw(); // Square::draw
delete shape;
}
在这种情况下,draw
函数必须在运行时解析,因为 shape
的基础类型可以在整个运行时修改。
你的代码没有问题,因为多态 类 virtual
函数调用在运行时使用虚函数 table 解析,事实上,这在 c++
.
从概念上讲,因为 draw() 是一个虚拟方法,rect->draw()
将始终查询 rect
指向的 Rectangle
派生对象的 vtable
。
不过
如果编译器可以证明 rect
实际上指向 Rectangle
的一个实例,而不是从它派生的其他 class 的实例,它会覆盖 [=16] =] 方法,则允许(但不是必需)绕过多态查找,从而节省了几次内存提取。
class Shape {
public:
virtual void draw() = 0;
. . .
};
class Circle : public Shape {
public:
void draw() { . . . }
. . .
};
class Rectangle : public Shape {
public:
void draw() { . . . }
. . .
};
class Square : public Rectangle {
public:
void draw() { . . . }
. . .
};
Rectangle* rect = new Rectangle;
rect->draw(); // Statically bound to the draw in the Rectangle class
在课本中,"concepts of programming language, 10th",
有一部分是关于动态方法绑定的。
我认为rect指向的对象类型不能静态解析,因为rect是多态引用类型。 rect 也可能在 运行 时间内引用 Sqaure 类型对象。
代码上面最后一行不正确??
考虑以下示例
int main
{
Shape* cir = new Circle;
Shape* rec = new Rectangle;
Shape* sqr = new Square;
cir->draw(); // Circle::draw
rec->draw(); // Rectangle::draw
sqr->draw(); // Square::draw
}
所有这些变量cir
、rec
和sqr
都是Shape*
,但由于多态性,它们将调用各自的draw
方法。当我们重新使用同一个变量时,这一点就更清楚了
int main
{
Shape* shape = new Circle;
shape->draw(); // Circle::draw
delete shape;
shape = new Rectangle;
shape->draw(); // Rectangle::draw
delete shape;
shape = new Square;
shape->draw(); // Square::draw
delete shape;
}
在这种情况下,draw
函数必须在运行时解析,因为 shape
的基础类型可以在整个运行时修改。
你的代码没有问题,因为多态 类 virtual
函数调用在运行时使用虚函数 table 解析,事实上,这在 c++
.
从概念上讲,因为 draw() 是一个虚拟方法,rect->draw()
将始终查询 rect
指向的 Rectangle
派生对象的 vtable
。
不过
如果编译器可以证明 rect
实际上指向 Rectangle
的一个实例,而不是从它派生的其他 class 的实例,它会覆盖 [=16] =] 方法,则允许(但不是必需)绕过多态查找,从而节省了几次内存提取。