• 关于c++中的new的使用


    我评价自己的C++水平还未入门的确不够准确,应该是远远未入门。

    感叹自己看书的时候如此粗心,C++Coder最基本的placement new的知识,今天才明白。

    如何在new一个对象的时候,使对象的空间并不在堆上分配,而是由使用者传入一个缓冲区给对象使用,且编译期会自动调用对象的构造函数?

    new这个C++头文件中(注意,是new,不是new.h),定义了一个全局的重载了的new操作符,可以达到上述的效果。看看我写的测试代码:

    //------------------------------------------------------------------------

    //test_new.cpp

    // g++ -o test_new test_new.cpp -Wall -Werror

    #include <stdio.h>

    #include <new>

    class MyClass

    {

    public:

    MyClass()

    {

    printf("constructor, %s %d ", __FILE__, __LINE__);

    }

    ~MyClass()

    {

    printf("destructor, %s %d ", __FILE__, __LINE__);

    }

    private:

    MyClass(const MyClass& rsh);

    MyClass& operator=(const MyClass& rsh);

    };

    void test()

    {

    char buf[10];

    MyClass* p = new (buf)MyClass;  // 构造函数被调用了

    printf("buf=%08X, p=%08X ", (unsigned int)buf, (unsigned int)p);  //发现对象的地址和缓冲区的地址是一致的

    //delete p;  //不能调用delete,因为没有placement delete

    }

    int main()

    {

    test();

    return 1;

    }

    //----------------------------------------------------------

    当然,指定缓冲区的方式构造了对象,是不需要管理空间释放的工作的。

    可是,如何只调用析构函数,而又不删除空间呢?

    可以手动调用析构函数来实现:

    p->~MyClass();

    虽然有三种new的用法其一是new operator,也叫new表达式其二是operator new,也叫new操作符。这两个英文名称起的也太绝了,很容易搞混,那就记中文名称吧。new表达式比较常见,也最常用,例如:

    string* ps = new string("abc");

    上面这个new表达式完成了两件事情:申请内存和初始化对象。

    new操作符类似于C语 言中的malloc,只是负责申请内存,例如:

    void* buffer = operator new(sizeof(string));

    注 意这里多了一个operator。这是new的第二个用法,也算比较常见吧。

    那么第三个用法就不很常见了,官方的说法是placement new,它用于在给定的内存中初始化对象,也就是说你手中已有一块闲置的内存,例如:

    void* buffer = operator new(sizeof(string));//那么现在buffer是你所拥有闲置内存的指针

    buffer = new(buffer) string("abc"); //调用了placement new,在buffer所指向的内存中初始化string类型的对象,初始值是"abc"

    事实上,placement new也是new表达式的一种,但是比普通的new表达式多了一个参数,当然完成的操作和返回值也不同。

    因此上面new的第一种用法可以分解两个 动作,分别为后面的两种用法。

    与new对应的delete没有三种语法,它只有两种,分别是delete operator和operator delete,也称为delete表达式和delete操作符。delete表达式和new表达式对应,完成对象的析构和内存的释放操作。而delete 操作符只是用于内存的释放,和C语言中的free相似。例如:

    string* ps = new string("abc");
    ...
    delete ps; //调用delete表达式,先析构再释放
    void* buffer = operator new(sizeof(string));
    ...
    operator delete(buffer); //释放

    那么为什么没有和 placement new对应的那个delete呢?其实是有的。placement new是在指定位置初始化对象,也就是调用了构造函数,因此与之对应的就是析构函数了,只不过它不叫placement delete而已。

    void *pv = operator new(sizeof(vector<int>));
    pv = new(pv) vector<int>(8, 0);
    ...
    static_cast<vector<int>* >(pv)->~vector(); // call destruct function
    operator delete(pv); // free memory
    pv = NULL;

    总结:c++中new的是地址,也就是 = 左侧应该是一个地址。而new的右侧应该是一个类型

     
     
  • 相关阅读:
    HTML 拖放 和 地理定位
    HTML web存储
    HTML 语义元素 和 MathML元素
    Docker Swarm
    Docker Machine
    Docker Compose
    Docker 的网络模式
    数据共享与持久化
    镜像和容器的基本操作
    Docker 简介
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/12787339.html
Copyright © 2020-2023  润新知