在this question中,当编译器不支持 new 并且放置 new 时,会创建工厂方法。显然,如果以某种方式复制放置 new 所做的所有必要步骤,可以使用malloc()制作一些合适的解决方案。
展示位置新做什么 - 我会尝试列出并希望不要错过任何内容 - 除了以下内容?
还有其他什么行动?
答案 0 :(得分:6)
放置new
执行常规new
所做的一切,除了分配内存。
我认为你基本上已经把所发生的事情钉在了一些细微的说明上:
构造/初始化的顺序如下:
答案 1 :(得分:4)
相应地设置vtable指针
这部分几乎完全是实现定义的。您的编译器可能不使用vtables。可能有多个vtable指针,或者指向不是vtable的东西的一个或多个指针。多重继承总是很有趣,虚拟基类也是如此。不保证此元数据可以使用memcpy
复制到另一个对象,因此指针不必是绝对的。那里可能存在相对于对象指针本身的偏移。
因此无法概括实现的功能,特别是因为您所拥有的不是C ++标准的实现。如果它通过省略“新”来削减角落,可能有充分的理由,因为它认为你不应该在目标平台上使用它,那么谁知道它忽略的语言的其他规则。如果可以使用malloc和一些指针推动来模拟“new”,那么为什么编译器不仅仅实现新的呢?我认为您需要提出用您的特定编译器和平台标记的问题,以便编译器上的任何专家都能做出响应。
答案 2 :(得分:0)
@laalto回答一般都是正确的。但是,有一个例外证明了这一规则。
vtable指针初始化为构造函数调用的一部分,而不是单独的。
Microsoft C ++编译器知道所谓的本地vftables,即vftables是DLL的本地,并且将为每个导入的类克隆。这是因为编译器想要提供一个修改后的析构函数,它包装了原始的析构函数(s.a. here)。
每当构造导入类的对象时,编译器都会在构造函数调用后生成用本地指针覆盖原始vftable指针的代码。此代码也会出现在新的来电中。
除了上面的帖子中提到的那些之外,还存在另一种解决方法。此解决方法不会强制您更改原始头文件。请看这里:https://godbolt.org/g/YQsffY