zoukankan      html  css  js  c++  java
  • 关于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的右侧应该是一个类型

     
     
  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/12787339.html
Copyright © 2011-2022 走看看