new深入剖析 c++

来源:互联网 发布:ae cs4软件下载 编辑:程序博客网 时间:2024/06/05 09:15

结论1:new操作符会调用new函数和构造函数,我们只能重载new函数。new操作符不像其他操作符一样是一个显示的函数。以下1.1和1.2都是new操作符,即只要不是显示的函数调用,其他的都是new操作符

结论2:new操作符要么匹配成员new函数,要么匹配全局new函数,不能同时匹配成员和全局new函数

结论3:new操作符有两个过程,一是调用operator new()函数,二是调用构造函数在operator new()返回的地址上构造对象

----------------------------------------------------------------------------------------------------------------------------------------------

一、new 的语法有

1.1 A* ptr = new A(constructor-para-list);

1.2 A* ptr = new (para-list) A(constructor-para-list);

1.3 A* ptr = operator new(size);

二、new 的上述语法涉及到的函数

2.1 void* operator new(size_t size)

C++提供了一个全局的 void* operator new(size_t size)函数,该函数的作用就是用来申请空间,其底层实现就是使用了malloc,实现代码可在文章后面附录1看到。该函数可以被重载(重载为类的成员函数或全局函数都可以),但是重载函数的第一个参数必须是size_t 类型。

三、接下来,我们来看下一个包含new的语句到底做了什么

请看下面的代码

class X{public:    X() { cout<<"constructor of X"<<endl; }    ~X() { cout<<"destructor of X"<<endl;}    void* operator new(size_t size,string str)    {        cout<<"operator new size "<<size<<" with string "<<str<<endl;        return ::operator new(size);            }    void operator delete(void* pointee)    {        cout<<"operator delete"<<endl;        ::operator delete(pointee);    }private:    int num;    int numb;};int main(){    X *px = new("A new class") X;    delete px;    return 0;}


可以看出,语句 X* px = new("A new class") X; 调用了重载的operator new函数,以及X的默认构造函数。

operator new()函数可以重载为成员函数,也可以重载为全局函数。

如果成员函数有重载operator new()函数(重载一次或多次),那么new操作符调用的一定是operator new()成员函数中的某一个,不能调用全局的operator new()函数。如果operator new()没有被重载为成员函数,那么new操作符调用的是全局operator new()中的某一个

成员函数中有operator new()重载函数:

class X{public:    X() { cout<<"constructor of X"<<endl; }    ~X() { cout<<"destructor of X"<<endl;}        void* operator new(size_t size,string str){    cout<<"operator new size "<<size<<" with string "<<str<<endl;    return ::operator new(size);        }    void operator delete(void* pointee)    {        cout<<"operator delete"<<endl;        ::operator delete(pointee);    }private:    int num;    int numb;};    int main(){X* px = new X;    return 0;}

提示找不到被调用的匹配函数X::operator new(size_t),因为只能调用成员new函数,不能调用全局new函数。

成员函数中没有operator new()重载函数:

class X{public:    X() { cout<<"constructor of X"<<endl; }    ~X() { cout<<"destructor of X"<<endl;}      void operator delete(void* pointee)    {        cout<<"operator delete"<<endl;        ::operator delete(pointee);    }private:    int num;    int numb;};     void* operator new(size_t size,string str){    cout<<"operator new size "<<size<<" with string "<<str<<endl;return ::operator new(size);        }int main(){X* px = new X;delete px;    return 0;}

四、delete 扩展

delete操作符先调用析构函数,再调用operator delete()函数。

operator delete()只能被重载为两种形式

4.1 void operator delete(void* ptr)

4.2 void operator delete(void* ptr, size_t size)

delete的用法就一种:delete ptr;

delete ptr; 调用的delete函数首先是4.1,只有当4.1找不到的时候,才会调用4.2;4.2中size的值实质上是sizeof(*ptr)

和new一样,如果成员函数有delete函数,那么delete操作符只会匹配成员delete函数,不会匹配全局delete函数。如果成员函数没有delete函数,则delete操作符只会匹配全局delete函数。

五、new、delete对

malloc - free // A* pa = (A*)malloc(sizeof(A)); free(pa);

operator new - operator delete // A* pa = operator new(sizeof(A)); operator delete(pa);

new - delete // A* pa = new A; delete pa;

                       // A* pa = new (para-list) A; delete pa;

new[] - delete[] // A* pa = new A[10]; delete[] pa;

六、placement new

placement new的用法就是 A* pa = new (ptr) A(constructor-para-list);实质上就是重载了 operator new()函数。它的效果就是在ptr开始的位置上构造一个A类的对象。

网上说其实现代码如下:

inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
上述的代码应该没问题:因为构造函数是在operator new()返回的地址上构造对象。
另外,placement new要包含头文件 <new>,因为重载的new函数是在该头文件中实现的


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老公嫌你烦了怎么办 2岁宝宝吃饭不嚼怎么办 2岁宝宝挑食厌食怎么办 孩子不爱和家长交流怎么办 孩子发烧在医院查不出病因怎么办 宝宝乳牙长歪了怎么办 两岁宝宝不爱吃水果怎么办 两岁宝宝不吃水果怎么办 一岁的宝宝上火了怎么办 吃水果嘴唇肿了怎么办 二岁宝宝不爱吃饭怎么办 小婴儿便秘但不爱喝水怎么办 宝宝只吃水果不吃饭怎么办 一岁宝宝不喜欢吃水果怎么办 1岁宝宝不吃水果怎么办 一岁半宝宝吃水果拉肚子怎么办 大人发烧了怎么办如何退烧 怀孕后不爱吃水果怎么办 不敢吃水果了怕虫怎么办 宝宝发烧38度不出汗怎么办 1岁宝宝喜欢含饭怎么办 3岁宝宝喜欢含饭怎么办 孩子咳嗽发烧怎么办最有效 孩子咳嗽打哈切流鼻涕发烧怎么办 孩子香蕉吃多了怎么办 80多岁老人发烧怎么办 小孩香蕉吃多了怎么办 7个月宝宝缺钙怎么办 宝宝脖子被汗淹到红了脱皮怎么办? 小儿出汗多咳嗽怎么办吃什么 牛高烧不退怎么办最好 猪体温低不吃食怎么办 小孩发烧咳嗽怎么办吃什么药 大晚上发烧39度怎么办 胃受凉了老打嗝怎么办 大人发低烧怎么办如何退烧 吃了退热药不退热怎么办 猪持续高烧不退怎么办 猪感冒了不吃食怎么办 6岁儿童发烧38度怎么办 5岁儿童发烧38度怎么办