我会做出一个疯狂的猜测:
C ++构造函数和析构函数根本不是函数:它们是宏。它们被内联到创建对象的范围和销毁对象的范围中。反过来,没有构造函数或析构函数,对象只是IS。
实际上,我认为该类中的其他函数也不是函数,而是DONT会内联的内联函数,因为您要获取它们的地址(编译器意识到您已经进入了该内联函数,而不是内联或内联代码到函数中,优化该功能),然后该功能似乎“仍然存在”,即使您未解决该问题也不会。
C ++“对象”的虚拟表与JavaScript对象不同,您可以在其中获取其构造函数并在运行时通过来创建对象new XMLHttpRequest.constructor
,而是指向匿名函数的指针的集合,这些指针充当与该对象进行接口的方式,不包括创建对象的能力。而且“删除”对象甚至没有意义,因为就像试图删除一个结构一样,您不能:它只是一个堆栈标签,只需在另一个标签下随意写就可以:使用一个类作为4个整数:
/* i imagine this string gets compiled into a struct, one of which's members happens to be a const char * which is initialized to exactly your string: no function calls are made during construction. */
std::string a = "hello, world";
int *myInt = (int *)(*((void **)&a));
myInt[0] = 3;
myInt[1] = 9;
myInt[2] = 20;
myInt[3] = 300;
没有内存泄漏,没有问题,除了您实际上浪费了为对象接口和字符串保留的一堆堆栈空间,但是这不会破坏您的程序(只要您不尝试使用它)再次作为字符串)。
实际上,如果我以前的假设是正确的:字符串的全部开销就是存储这32个字节和常量字符串空间的开销:这些函数仅在编译时使用,并且在插入后也可能被内联和抛弃对象的创建和使用(就像您正在使用结构,并且仅在没有任何函数调用的情况下直接引用它一样,请确保存在重复的调用而不是函数跳转,但这通常更快并且使用更少的空间)。本质上,每当您调用任何函数时,编译器都将用该指令替换该调用以按实际方式进行操作,但语言设计人员已设置了例外情况。
简介:C ++对象不知道它们是什么。与它们接口的所有工具都是静态内联的,并且在运行时会丢失。这使得使用类和使用数据填充结构一样高效,并且直接使用该数据而无需调用任何函数(这些函数是内联的)。
这与COM / ObjectiveC和javascript的方法完全不同,后者会动态保留类型信息,但会浪费运行时开销,内存管理和构造调用,因为编译器无法丢弃此信息:这是必要的用于动态调度。反过来,这使我们能够在运行时与程序“对话”,并通过具有可反射的组件在运行时对其进行开发。