重载新运算符 - 此代码不应该产生错误

时间:2018-02-12 22:42:19

标签: c++ c++11

我试图了解操作员new是如何重载的,并从我在网上做的研究中得到了这个。 新的运算符重载函数采用size_t类型。但是在我的main中,我使用new Dummy()来调用它。根据我的理解,Dummy被隐式转换为size_t正确吗?然后在假人之后()会发生什么?不应该导致错误吗?

void* operator new(size_t sz)
{
  void* m = malloc(sz);
  std::cout<<"User Defined :: Operator new"<<std::endl;

  return m;
}

class Dummy
{
public:
  Dummy()
  {
    std::cout<<"Dummy :: Constructor"<<std::endl;
  }
  ~Dummy()
  {
    std::cout<<"Dummy :: Destructor"<<std::endl;
  }
};


int main()
{
    Dummy * dummyPtr = new Dummy();
}

2 个答案:

答案 0 :(得分:1)

涉及new关键字有两件事:

首先,您拥有new运算符,标准定义了不同的重载,您可以覆盖它们或创建新的。它的责任是分配N大小的内存并向其返回void*。您甚至可以创建自己的new运算符来分配内存并获取一个额外的参数:

void* operator new(size_t sz, char x) // x is a placement param
{
    std::cout << "User Defined :: Operator new" << std::endl;
    return ::operator new(sz); // standard new
}

auto* x = new('*') int(234); // our overload

但是等一下,new运算符如何获得我们想要实例化的类型的大小?

我们的朋友new expression刚进入游戏!

将新表达式想象成一些用于调用new运算符的语法糖。它有这样的结构:

new(placement_params) type+initializer

这意味着对于new int(22),表达式将为new(no placements) int + copy_initializer(22),并且它将在内部调用传递该类型大小的new operator

New运算符将返回一个void*,指向它刚刚分配的内存,而new expression的正确大小将初始化该内存。在此示例中,调用复制初始值设定项

答案 1 :(得分:0)

new是一种语言结构,而不是常规函数,它具有特殊的语法和方便性。 new expressionoperator new

之间存在差异

以下两者构造Dummy,但一个使用本地存储,另一个使用动态存储。因此,在这两种情况下Dummy()都是构造函数调用的一部分,在第二种情况下,new没有直接绑定。auto d1 = Dummy(); auto d2 = new Dummy();

Dummy

这里新表达式都使用提供的构造函数和参数分配空间并在该空间中构造sizeof Dummy。空间量由编译器通过operator new确定。

当您重载默认的observe()时,它将使用您的用户定义函数来进行分配,但不使用构造(由新表达式完成)。