在阅读了大量有关 VTable 的内容之后,我仍然有一个 Unresolved 问题。
给定下一节课:
#include <iostream>
using namespace std;
class Shape {
public:
int* a;
Shape(){
cout<<"default Shape ctor"<<endl;
a = new int(15); // default
}
Shape(int n){
a = new int(n);
cout<<"Shape(n) constructor"<<endl;
}
// copy constructor
Shape(const Shape& s){
cout<<"copy constructor"<<endl;
a = new int(*(s.a));
}
Shape& operator=(const Shape& s){
cout<<"operator="<<endl;
if (&s == (this))
return (*this);
// this.clear();
a = new int(*(s.a));
return (*this);
}
virtual void draw(){
cout<<"print Shape the number is "<<*a<<endl;
};
virtual ~Shape(){
delete a;
cout<<"Shape distructor"<<endl;
}
};
class Circle : public Shape {
public:
int b;
Circle() {
cout<<"Circle constructor"<<endl;
b=5;
}
virtual void draw() {
cout<<"print Circle. The number is "<<b<<endl;
}
~Circle(){
cout<<"Circle distructor"<<endl;
}
};
和以下测试:
static void test2(){
Circle* c = new Circle();
cout<<"size of *c is "<<sizeof(*c)<<endl;
Shape* s = c;
cout<<"size of *s is "<<sizeof(*s)<<endl;
s->draw();
}
我得到这个输出:
default Shape ctor
Circle constructor
size of *c is 12
size of *s is 8
print Circle. The number is 5
我的问题是:我知道 s 如何寻址 Circle::draw,但 s 如何知道变量 b=5? 如该测试所示,s 没有此信息。我在这里缺少什么?
谢谢!
好的伙计们。感谢您的快速回答...
我从您的回答中得知 Circle::draw() (*this) 是 Circle 类型。好的。 我的问题现在变成了:因为我只希望 s 是 Shape* 类型,也就是说,我的程序只需要 Shape 特性。接下来的 4 个字节(Circle 中的 b 变量)是否有可能被编译器以某种方式占用?如果是这样,显然 Circle::draw() 将无法按预期工作。
如果不是,编译器如何知道在 s 的“结束”之后我将需要接下来的 4 个字节?
最佳答案
您缺少的是 s
指向一个 Circle
—— 而 Circle
包含一个名为 b 的数据成员
。当调用 s->draw();
时,编译器会调用 Circle::draw()
,如您所见,并在 Circle::draw() 内
,*this
(即当前对象)的类型是 Circle
而不是 Shape
。所以 Circle::draw()
可以访问 b
。
编辑:在回答您的新问题时,s
是指向 Shape
的指针——您所做的只是存储相同的地址(到内存中 Circle
对象的开头)但具有不同的类型(Shape*
而不是 Circle*
)。底层的 Circle
对象存在于内存中,与指向它的事物无关。您不能通过 s
直接访问 Circle
特定的数据成员,因为它是一个 Shape*
,但是虚拟调度机制意味着当您调用通过 s
的虚拟成员函数,调用被转发到 Circle
中的适当成员函数,即 s->draw();
实际上结束了调用 Circle::draw
。没有危险,因为将底层 Circle
对象的地址存储在 Shape*
中,底层 Circle
对象将以某种方式 ' sliced',去掉 b
数据成员。切片仅在您执行此类操作时发生:
Circle c;
Shape s = c; // copies the Shape data members across from c, but slices off the rest
关于c++ - 虚表和多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5512058/