Eya*_*yal 5 c++ inheritance vtable
在阅读了很多关于VTables之后,我仍然有一个悬而未决的问题.
鉴于下一堂课:
#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;
}
};
Run Code Online (Sandbox Code Playgroud)
以及以下测试:
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();
}
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
default Shape ctor
Circle constructor
size of *c is 12
size of *s is 8
print Circle. The number is 5
Run Code Online (Sandbox Code Playgroud)
我的问题是:我知道如何处理Circle :: draw,但是怎么知道变量b = 5?如本测试所示,s没有此信息.我在这里错过了什么?
谢谢!
好,朋友们.谢谢你的快速回答......
我从你的答案中得知,在Circle :: draw()(*this)中是Circle类型.好.我现在的问题已经变成这样:因为我只是想小号是一个Shape*类型,也就是说,我需要在我的程序只有外形气质.是否可能以某种方式由编译器接下来的4个字节(Circle中的b变量)?如果是这样,显然Circle :: draw()将无法正常工作..
如果没有,编译器如何知道在s的"结束"之后我将需要接下来的4个字节?
您缺少的是s指向Circle-- 并且Circle包含一个名为 的数据成员b。当s->draw();调用 时,编译器会调用Circle::draw(),如您所知,并且在 中, (即当前对象)Circle::draw()的类型不是。因此可以访问.*thisCircleShapeCircle::draw()b
编辑:为了回答你的新问题,s是一个指向-Shape你所做的就是存储相同的地址(到Circle内存中对象的开头)但使用不同的类型(Shape*而不是Circle*)。Circle无论指向它的东西如何,底层对象都存在于内存中。您不能直接访问Circle特定的数据成员 through ,因为它是 a ,但虚拟调度机制意味着当您调用虚拟成员函数 through 时,该调用将转发到 中的相应成员函数,即实际上最终调用。由于将底层对象的地址存储在 a 中,底层对象不会以某种方式被“切片”,从而删除数据成员。仅当您执行此类操作时才会发生切片:sShape*sCircles->draw();Circle::drawCircleShape*Circleb
Circle c;
Shape s = c; // copies the Shape data members across from c, but slices off the rest
Run Code Online (Sandbox Code Playgroud)