| class Shape { | |
| public: | |
| virtual double Area() { return 1.0; } | |
| virtual double Perimeter() { return 1.0; } | |
| // Note that destructors generate two entries in the vtable: base object | |
| // destructor and deleting destructor. | |
| virtual ~Shape() = default; | |
| }; | |
| class Rectangle : public Shape { | |
| public: | |
| ~Rectangle() override = default; | |
| double Area() override { return 2.0; } | |
| double Perimeter() override { return 2.0; } | |
| virtual void RectangleOnly() {} | |
| // This *shouldn't* show up in the vtable. | |
| void RectangleSpecific() { return; } | |
| }; | |
| // Make a class that looks like it would be virtual because the first ivar is | |
| // a virtual class and if we inspect memory at the address of this class it | |
| // would appear to be a virtual class. We need to make sure we don't get a | |
| // valid vtable from this object. | |
| class NotVirtual { | |
| Rectangle m_rect; | |
| public: | |
| NotVirtual() = default; | |
| }; | |
| int main(int argc, const char **argv) { | |
| Shape shape; | |
| Rectangle rect; | |
| Shape *shape_ptr = ▭ | |
| Shape &shape_ref = shape; | |
| shape_ptr = &shape; // Shape is Rectangle | |
| NotVirtual not_virtual; // Shape is Shape | |
| return 0; // At the end | |
| } |