百科问答小站 logo
百科问答小站 font logo



C++ 中 new 和定位 new 的返回值都是 void*,却为什么可以被赋值给不同类型的指针? 第1页

  

user avatar   breakerzhao 网友的相关建议: 
      

这里有两个不同的东西,new expression(也叫 new operator)和 operator new()。

new expression 是语言内建机制,不能重载,我们常写的 new T、new T(param) 等就是这个,它返回有类型的指针 T*。new T 做两件固定的事,第一步调用 operator new(),第二步调用 T 的构造函数,这两步都由编译器自动产生。

operator new() 可以重载,它返回 void*,是一块未初始化的原始内存,随后控制返回到内建的 new expression 中。

placement new 的 operator new() 默认实现如下。它的第一个 size_t 是个必须有,但虚置无用的参数。它的功能就是返回已由用户提供的原始内存地址。

       void* operator new(size_t, void* loc) {     return loc; }      

常规的 new expression 执行过程如下:

       #include <new>  class Widget { public:     Widget(Param p) { /*...*/ }     ~Widget() { /*...*/ }     //... };  // 常规的 new expression Widget* pw = new Widget(param);  // 大致等价于以下过程: // [1] 直接调用 operator new() 函数分配原始内存 void* raw = operator new(sizeof(Widget)); // 上面作用类似下面这句 void* raw = malloc(sizeof(Widget));  // [2] 利用 placement new 调用 Widget 的构造函数 // 这里也是本题的关键: new expression 会将 void* 转换为有类型的指针 Widget* Widget* pw = new(raw) Widget(param);      

相应地,常规的 delete expression 执行过程如下:

       // 常规的 delete expression delete pw;  // 大致等价于以下过程: // [1] 手工调用 Widget 的析构函数 pw->~Widget(); // [2] 直接调用 operator delete() 函数释放原始内存 operator delete(raw); // 上面作用类似下面这句 free(raw);      

以上模拟的是 Widget 构造函数中没有抛出异常时的 new-delete 过程。

没有 placement delete expression 语法,只有 placement operator delete() 函数。在用 placement new 时,只要考虑手工调用 Widget 的析构函数即可,而 placement operator delete() 是 Widget 的构造函数中抛出异常时,由编译器自动调用的。




  

相关话题

  为什么C++头文件喜欢把一个类型通过typedef定义出无数个新名字,这有什么意义吗? 
  有没有什么程序库使得我们可以比较方便的在windows下使用比较新版本的opengl的? 
  <<深度探索c++对象模型>>中的虚继承看着蛋疼,感觉这在实际中也没多大用,需要继续深究吗? 
  倒序输出字符串c++为啥不行? 
  怎能给孩子讲用c++解决鸡兔同笼问题,百钱买百鸡等问题,也就是c++的for循环嵌套枚举? 
  如果 C# 当年设计成一个彻底编译到机器码的但有运行时的 AOT 语言,能不能真的拿来代替 C++? 
  为什么C++中virtual要翻译为虚函数? 
  #define 不是简单的替换吗,为什么下面的代码错误? 
  网上说 Java 的性能已经达到甚至超过 C++,是真的吗? 
  在C#中,如何实现跟native dll 中途的线程间通信? 

前一个讨论
C++整型有__int8、__int16、__int32等等,为什么还要short、int、long?
下一个讨论
游戏《原神》 北斗邀约中「真正的交易」是指的什么?





© 2024-12-18 - tinynew.org. All Rights Reserved.
© 2024-12-18 - tinynew.org. 保留所有权利