【问题标题】:Why does this implementation of the C++ 'new' operator work?为什么 C++ 'new' 运算符的这种实现有效?
【发布时间】:2013-01-09 12:26:08
【问题描述】:

我发现 AVR uC 的 C++ 编译器不支持 newdelete 运算符,但也有一个快速修复:

void * operator new(size_t size) 
{ 
  return malloc(size); 
} 

void operator delete(void * ptr) 
{ 
  free(ptr); 
}

我假设现在可以拨打new ClassName(args);

但是,我不确定这是如何工作的。例如,这里实际返回size_t 的是什么?我认为构造函数不会返回任何东西......

难道new 现在应该以不同的方式使用(与sizeof() 一起使用)?

【问题讨论】:

  • 不要混淆 new 和 operator new。是的,这有点棘手。您正在重载的 operator new 只是分配内存。您可以使用 malloc 或特殊的内存池,也可以对其进行装饰以帮助检测内存泄漏和无效删除等。
  • 这是否意味着它实际上根本没有实例化类或什么?你说的我有点困惑。
  • 始终牢记运算符 new(可以重载)和 new 表达式(通常用于在代码中创建新对象)是两个不同的东西。
  • @PlasmaHH,好吧,我不知道。希望编译器支持新的表达式。
  • @Yannbane:如果没有,它就不是 C++ 编译器。

标签: c++ memory malloc avr libc


【解决方案1】:

new T(args); 大致等价于以下内容。

void* storage = operator new(sizeof(T)); // obtain raw storage
call_constructor<T>(storage, args); // make an object in it

(这里call_constructor 应该调用T 的构造函数 使storage 成为该构造函数中的this 指针。)

operator new 部分获取请求的原始存储量,而构造函数调用是通过调用构造函数实际生成对象的部分。

问题中的代码只替换了operator new部分,即检索存储。当您使用new T(args) 时,sizeof 部分和构造函数调用均由编译器自动完成。


† 该语言有一种方法可以表达这种直接的构造函数调用,称为“placement new”,但为了清楚起见,我省略了它。

【讨论】:

  • 我认为operator 部分是定义语法的运算符的一部分...所以我需要在某处添加call_constructor 部分?
  • @Yannbane 不,编译器知道该怎么做。在这一点上,我的答案更加明确。
  • 好的,我刚刚了解到“new expression”和“operator new”是两个不同的东西,所以我弄清楚了那部分。谢谢!
  • 对于 call_constructor 你可以写 new(storage) T(args);当然
  • @CashCow 是的,这就是我在脚注中提到的内容,但我认为在混合中添加另一个涉及new 的语法会使解释更加混乱。 :(
【解决方案2】:

根据编译器名称 (uC),我推测它是用于嵌入式控制器的。这是有道理的,因为您很少需要使用嵌入式设备进行动态内存管理,但可能会从“C with classes”中受益。希望它支持'placement new',这样你就可以真正使用 C++。

如果你的编译器不支持 new & delete,那它就不是一个真正的 C++ 编译器了!

我认为关键字“new”有效地转换为:

Object* pointer = (Object *)new(sizeof Object);
pointer->Object_Constructor(args);

【讨论】:

    猜你喜欢
    • 2019-07-13
    • 2013-12-17
    • 1970-01-01
    • 2011-06-19
    • 2011-06-18
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    • 2013-08-27
    相关资源
    最近更新 更多