我试图了解操作员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();
}
答案 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 expression和operator new
以下两者构造Dummy
,但一个使用本地存储,另一个使用动态存储。因此,在这两种情况下Dummy()
都是构造函数调用的一部分,在第二种情况下,new
没有直接绑定。auto d1 = Dummy();
auto d2 = new Dummy();
。
Dummy
这里新表达式都使用提供的构造函数和参数分配空间并在该空间中构造sizeof Dummy
。空间量由编译器通过operator new
确定。
当您重载默认的observe()
时,它将使用您的用户定义函数来进行分配,但不使用构造(由新表达式完成)。