当前位置:   article > 正文

C++new的几种用法详解_c++ new

c++ new

1、new operator

new operator 指的就是new操作符,它分为两个阶段的操作:

(1)调用::operator new 申请内存(相当于C语言的malloc)

(2)调用类的构造函数

#include<iostream>

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}
};

Fun* ptr1 = new Fun;  
delete ptr1;
ptr1 = nullptr;

// 输出结果
// call constructor
// call destructor
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

另外,需要注意的是new operator操作符是不能被重载的。

2、operator new

operator new操作符单纯申请内存,并且是可以重载的函数。调用operator new申请内存,内存申请的大小为自定义类Fun的大小。使用operator new 和 operator delete并不会调用构造函数和析构函数,因为其仅仅具有申请内存的功能

Fun* ptr2 = (Fun*)::operator new(sizeof(Fun));
::operator delete ptr2;
ptr2 = nullptr;

// 加上::代表的是全局,因为operator可以重载
// 此时编译器并不会输出call constructor和call destructor
// 由此可以证明operator仅具有申请内存的功能
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(1)重载operator new 操作符:

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}

    void* operator new(size_t size)
    {
        std::cout<<"operator new"<<std::endl;
        return ::operator new(size);
    }
    void operator delete(void* ptr)
    {
        std::cout<<"operator delete"<<std::endl;
        ::operator delete(ptr);
        ptr = nullptr;
    }
};  

Fun* ptr3 = new Fun;  
delete ptr3;

// 此时输出的是:  
// operator new
// call constructor
// call destructor
// operator delete 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

由上述例子可以知道,Fun对象的构造与删除调用了重载的operator new和operator delete。

(2)operator new的另外一种重载版本:

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}

    void* operator new(size_t size)
    {
        std::cout<<"operator new"<<std::endl;
        return ::operator new(size);
    }
    void* operator new(size_t size, std::string str)
    {
        std::cout<<"operator new version 2: "<<str<<std::endl;
        return ::operator new(size);
    }
    void operator delete(void* ptr)
    {
        std::cout<<"operator delete"<<std::endl;
        ::operator delete(ptr);
        ptr = nullptr;
    }
};  

Fun* ptr4 = new("this is my func") Fun;  
delete ptr4;

// 此时输出的是:  
// operator new version 2: this is my func
// call constructor
// call destructor
// operator delete 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

3、placement new

placement new 又称为定位new运算符,它能够让程序员指定需要使用的位置。定位new运算符直接使用传递给它的地址,它不负责判断哪些内存单元已被使用,也不查找未使用的内存块。这将一些内存管理的负担交给了程序员。

char* buf[128]; // 创建一块内存池
int* p1 = new(buf)int[10];
for(int i=0;i<10;++i)
    p1[i]=i+1;

std::cout<<"buf的地址:"<<(int*)buf<<std::endl;
std::cout<<"p1数组的地址:"<<p1<<std::endl;

int* p2 = new(buf)int;
std::cout<<"p2的地址:"<<p2<<std::endl;

int* p3 = new(buf+10*sizeof(int))int;
std::cout<<"p3的地址:"<<p3<<std::endl;

/*
    输出结果:
    buf的地址:0x7ffe318d6d70
    p1数组的地址:0x7ffe318d6d70
    p2的地址:0x7ffe318d6d70
    p3的地址:0x7ffe318d6eb0
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/824930
推荐阅读
相关标签