C++动态对象.如何在运行时确定对象大小?
C++ dynamic objects. How is object size determined during runtime?
我不明白一件事。例如,我声明类 A 和类 B 是 A 的子级:
class A {
public:
int a;
}
class B : public A {
public:
int b;
}
显然,如果我创建 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)
但是,如果我创建动态实例,然后稍后释放它们,该怎么办?
A * instanceAPointer = new A();
A * instanceBPointer = new B();
这些是不同类的实例,但程序会将它们视为类 A 的实例。使用它们时这很好,但是释放它们呢?要释放分配的内存,程序必须知道要释放的内存大小,对吗?
所以如果我写
delete instanceAPointer;
delete isntanceBPointer;
程序如何知道,从每个指针指向的地址开始,它应该释放多少内存?因为显然对象具有不同的大小,但程序认为它们是A型。
谢谢
我假设你知道删除是如何工作的。
至于delete
知道如何清理继承的实例。这就是在继承上下文中使用virtual
析构函数的原因,否则将具有未定义的行为。基本上,析构函数与其他所有virtual
函数一样,是通过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 */ }
}
这就是为什么这将起作用;
A* a = new B();
delete a;
通过vtable
,析构函数~B()
将由delete
调用。由于编译器在派生类中隐式插入基类的析构函数调用,因此将在~B()
中调用A
的析构函数。
如果通过指向基子对象的指针删除对象,并且子对象的类没有虚拟析构函数,则行为是未定义的。
另一方面,如果它确实具有虚拟析构函数,则虚拟调度机制负责为正确的地址(即完整的、派生最多的对象)释放正确的内存量。
您可以通过将dynamic_cast<void*>
应用于任何适当的基子对象指针来自己发现派生最多的对象的地址。(另请参阅此问题。
要释放分配的内存,程序必须知道要释放的内存大小,对吧?
如果你考虑C库malloc
和free
,你会发现调用free
时不需要指定要释放的内存量,即使在这种情况下free
提供了void*
所以没有办法推断它。 相反,分配库通常要么记录,要么可以推断出足够的内存,以便仅指针就足以执行释放。
对于C++释放例程来说,这仍然是正确的:如果基类提供了自己的static void operator delete(void*, std::size_t)
并且基类析构函数virtual
,那么它将被传递动态类型的大小。 默认情况下,释放最终会达到不会被赋予任何大小的::operator delete(void*)
:分配例程本身必须有足够的知识才能运行。
分配例程的工作方式有多种,包括:
-
存储分配的大小
-
从相同大小的块池中分配大小相似的对象,以便进入该池的任何指针都隐式与该块大小相关
- C++中的动态对象与非动态对象
- 对具有动态分配的内存和析构函数的类对象的引用
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 生成文件:动态源文件名和对象目录
- 我们可以通过 IPC 传递具有动态管理成员的类对象吗?
- 使用动态实例化的对象填充矢量的快速方法
- 如何在 Cheerp/js 中迭代动态命名的对象?
- 销毁C++中动态分配的内存(数组对象)
- 创建动态对象并将其推送到矢量中
- 删除包含包含动态对象的 STL 容器的智能指针
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- 如何访问对象动态数组中的私有成员变量?
- 如果您为类的一个对象动态分配内存作为参数,会发生什么
- Cython 中对象动态大小的数组
- malloc分配的对象动态类型是什么
- C++按属性排序的对象动态数组
- visual C++新与Malloc的对象动态内存阵列