C++ new运算符源码查看 对象的构造函数调用以及指针类型的转换在哪里完成

西昆仑 发布于 2012/05/27 16:04
阅读 3K+
收藏 0

今天在测试程序测试的过程中,发现用new运算符申请空间失败,跟踪并分析了一下new的源码

1.  operator new[]的代码

void *__CRTDECL operator new(size_t) /*_THROW1(std::bad_alloc)*/;

void * operator new[]( size_t cb )
{
    void *res = operator new(cb);
    RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
    return res;
}

 

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)      //申请空间
                if (_callnewh(size) == 0)    //若申请失败则调用处理函数
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);    //  #define _RAISE(x)	::std:: _Throw(x) 抛出nomem的异常
                }

        return (p);
        }

问题1: 原本我们的理解是,利用new运算符去创建对象,会做如下工作: 
申请内存空间
调用对象的构造函数初始化对象
返回对象类型的指针

但是我们在源码中发现new中只是做了申请内存空间的工作,
那构造函数的调用,以及指针类型的转换,是在哪里做的?由谁做的?

问题2:
在C++中,运算符和函数究竟有什么区别?
我理解的,运算符本身是语言本身自带的,不能自定义运算符,而函数是由用户自定义的。
运算符可以重载,函数也可以重载
只想到这么些了。

加载中
0
河边一枝柳

new是C++的操作符,你调试的只是new操作符的第一部分调用new函数进行空间分配,第二部分是对对象调用构造函数(是指类类型)。

我想这也是为什么new叫做一个操作符,而不作为一个函数的原因。因为如果new仅仅是一个函数调用,那么他只能做到申请空间,而无法在new函数内实现类对象的构造函数调用。

另外看下测试结果,其中base为类类型:

	base *p = new base;
0031140D  push        1    
0031140F  call        operator new (311195h) 
00311414  add         esp,4 
00311417  mov         dword ptr [ebp-0F8h],eax 
0031141D  mov         dword ptr [ebp-4],0 
00311424  cmp         dword ptr [ebp-0F8h],0 
0031142B  je          main+70h (311440h) 
0031142D  mov         ecx,dword ptr [ebp-0F8h] 
00311433  call        base::base (3110EBh) 
00311438  mov         dword ptr [ebp-10Ch],eax 
0031143E  jmp         main+7Ah (31144Ah) 
00311440  mov         dword ptr [ebp-10Ch],0 
0031144A  mov         eax,dword ptr [ebp-10Ch] 
00311450  mov         dword ptr [ebp-104h],eax 
00311456  mov         dword ptr [ebp-4],0FFFFFFFFh 
0031145D  mov         ecx,dword ptr [ebp-104h] 
00311463  mov         dword ptr [ebp-14h],ecx 

比较清晰

河边一枝柳
回复 @西昆仑 : ALt + 8
西昆仑
西昆仑
我刚想看汇编代码,就是没找到那个快捷键,怎么看汇编的呢?
0
c
crazybird

首先,new运算符肯定不只是申请空间,不然直接malloc不就行了

new除了申请空间外,还标明所申请空间存放的对象类型,然后编译器会查找对应类型的构造函数,对空间进行初始化

友情互访,你懂的!http://blog.csdn.net/crazyingBird

c
crazybird
回复 @西昆仑 : new属于运算符,是编译器支持的,所以编译器在遇到new时所执行的操作应该是编译器自定义的
西昆仑
西昆仑
对,逻辑是知道的。就是想知道对象构造函数的调用以及指针类型的转化是在哪里做的。因为函数中没有体现出了啊
0
c
crazybird
我理解的,运算符应该是语言定义的,但其具体行为应该是编译器支持的,也就是编译器实现的,但函数完完全全是用户自己定义的,求改正
西昆仑
西昆仑
那运算符重载呢
0
c
crazybird
csdn已经有人发过博了:http://blog.csdn.net/hongjiqin/article/details/3941718,关于new运算符的,比较详细
河边一枝柳
和我说的一样哈
0
涧水潺湲
对于c++中的内存分配,要分清楚new、operator new以及placement new, http://hubeihuyanwei.blog.163.com/blog/static/28205284201171722359640/,这篇博文做了简单的介绍,你也自己再去搜索一下。
西昆仑
西昆仑
已经弄清楚了,还是谢谢~
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部