C++动态对象.如何在运行时确定对象大小?

Mic*_*zov 5 c++ oop inheritance object dynamic-memory-allocation

我不明白一件事.例如,我声明A类和B类是A的子类:

class A {
    public:
        int a;
}

class B : public A {
    public:
        int b;
}
Run Code Online (Sandbox Code Playgroud)

显然,如果我创建A或B的实例,它们在内存中的大小可以由类型确定.

A instanceA; // size of this will probably be the size of int (property a)
B instanceB; // size of this will probably be twice the size of int (properties a and b)
Run Code Online (Sandbox Code Playgroud)

但是如果我创建动态实例然后在以后释放它会怎样?

A * instanceAPointer = new A();
A * instanceBPointer = new B();
Run Code Online (Sandbox Code Playgroud)

这些是不同类的实例,但程序会将它们视为A类的实例.在使用它们时这很好但是如何释放它们呢?为了释放分配的内存,程序必须知道要释放的内存大小,对吧?

所以,如果我写

delete instanceAPointer;
delete isntanceBPointer;
Run Code Online (Sandbox Code Playgroud)

程序如何知道,有多少内存,从每个指针指向的地址开始,它应该是空闲的?因为很明显,对象具有不同的大小,但程序认为它们是A类型.

谢谢

Whi*_*TiM 6

我假设你知道删除是如何工作的.

至于如何delete清理继承的实例.这就是你在继承上下文中使用virtual析构函数的原因,否则你将有未定义的行为.基本上,析构函数就像其他virtual函数一样通过a调用vtable.

还要记得:C++编译器隐式地破坏了析构函数中的父类

class A {
    public:
        int a;
    virtual ~A(){}
}

class B : public A {
    public:
        int b;
    ~B() { /* The compiler will call ~A() at the very end of this scope */ }
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么这会起作用;

A* a = new B();
delete a;
Run Code Online (Sandbox Code Playgroud)

借助于vtable,析构函数~B()将被调用delete.由于编译器隐式地在派生类中插入基类的析构函数调用,因此A将调用析构函数~B().