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;
    }
};

и следующий тест:

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, но как узнать переменную b = 5? Как показывает этот тест, у s нет этой информации. Что мне здесь не хватает?

Спасибо!

Хорошо, ребята. Спасибо за ваши быстрые ответы ...

Из ваших ответов я узнал, что в Circle :: draw () (* this) имеет тип Circle. В ПОРЯДКЕ. Мой вопрос теперь изменился на следующий: потому что я хотел, чтобы s был типом Shape *, то есть мне нужны в моей программе только свойства Shape. Возможно ли, что следующие 4 байта (переменная b в Circle) каким-то образом будут взяты компилятором? Если так, то очевидно, что Circle :: draw () не будет работать должным образом ..

Если нет, как компилятор узнает, что мне понадобятся следующие 4 байта после "конца" s?

5
задан Eyal 1 April 2011 в 11:17
поделиться