c++ operator new 这在内部是如何工作的
c++ operator new how this works internally
例如我有一个简单的代码:
class B
{
};
class A
{
B b;
public:
A()
{
throw 1;
}
};
int main()
{
A* a = 0;
try
{
a = new A;
}
catch (int)
{
}
}
构造函数A抛出异常,则不会调用析构函数。但是 B 的析构函数将被调用。不会分配堆中的内存。我的问题是这在内部如何运作?首先是什么:构造 A 还是在堆中分配内存?那么,如果allocating是第一个,如果有exception怎么处理deallocating呢?否则,如果构造 A 是第一个,它是如何复制到堆中的?
- 内存已分配。
- 调用了A的构造函数。
- A的构造函数调用B的构造函数
- A 的构造函数抛出。
- 作为标准异常处理程序的一部分,B 的析构函数被调用(RAII 在工作)。
- 堆栈展开到调用方(主)。
- 内存已释放(因为对象未成功构造)。
未调用 A 的析构函数,因为对象未完全构造。但是,已完全构建的成员仍然被摧毁。
内存的自动释放方式与控件离开块时局部变量的销毁方式几乎相同。如果您熟悉 Java and/or C#,请将其视为不可见的 try-finally
结构。或者一系列这样的结构。
What will be first: constructing A
or allocating memory in the heap?
除非有内存,否则没有 space 可以构造对象的地方。内存分配总是先行;然后代码继续初始化。这适用于所有类型的内存分配,不仅是动态类型,因为构造函数在开始初始化对象之前需要有一个有效地址 this
。
If allocating is the first, how deallocating will be handled if there are exception?
编译器发出处理此处 "magic" 的特殊代码。此代码将为所有基 类 和成员(例如 B
)运行 析构函数,这些成员在代码进入 A
的构造函数时已完全构建。
例如我有一个简单的代码:
class B
{
};
class A
{
B b;
public:
A()
{
throw 1;
}
};
int main()
{
A* a = 0;
try
{
a = new A;
}
catch (int)
{
}
}
构造函数A抛出异常,则不会调用析构函数。但是 B 的析构函数将被调用。不会分配堆中的内存。我的问题是这在内部如何运作?首先是什么:构造 A 还是在堆中分配内存?那么,如果allocating是第一个,如果有exception怎么处理deallocating呢?否则,如果构造 A 是第一个,它是如何复制到堆中的?
- 内存已分配。
- 调用了A的构造函数。
- A的构造函数调用B的构造函数
- A 的构造函数抛出。
- 作为标准异常处理程序的一部分,B 的析构函数被调用(RAII 在工作)。
- 堆栈展开到调用方(主)。
- 内存已释放(因为对象未成功构造)。
未调用 A 的析构函数,因为对象未完全构造。但是,已完全构建的成员仍然被摧毁。
内存的自动释放方式与控件离开块时局部变量的销毁方式几乎相同。如果您熟悉 Java and/or C#,请将其视为不可见的 try-finally
结构。或者一系列这样的结构。
What will be first: constructing
A
or allocating memory in the heap?
除非有内存,否则没有 space 可以构造对象的地方。内存分配总是先行;然后代码继续初始化。这适用于所有类型的内存分配,不仅是动态类型,因为构造函数在开始初始化对象之前需要有一个有效地址 this
。
If allocating is the first, how deallocating will be handled if there are exception?
编译器发出处理此处 "magic" 的特殊代码。此代码将为所有基 类 和成员(例如 B
)运行 析构函数,这些成员在代码进入 A
的构造函数时已完全构建。