代码之家  ›  专栏  ›  技术社区  ›  Amir Zadeh

第二个是什么?

  •  14
  • Amir Zadeh  · 技术社区  · 15 年前

    int * x = new int [1] ;
    int * y = new (x) int;
    

    在第二行之后,x和y具有相同的值(指向相同的位置)。y=x和第二行有什么区别?它是一个构造器还是什么?

    5 回复  |  直到 15 年前
        1
  •  13
  •   Oliver Charlesworth    15 年前

    它是 placement new int 在被指的记忆里 x .

    如果您尝试:

    int * x = new int [1];
    *x = 5;
    std::cout << *x << std::endl;
    int * y = new (x) int;
    *y = 7;
    std::cout << *x << std::endl;
    

    5
    7
    
        2
  •  4
  •   Community Mohan Dere    8 年前

    这叫做 placement new . 它允许您在已分配的内存中构造一个对象。

    前面的主题讨论 where and how it is useful for .

        3
  •  3
  •   Ferruccio    15 年前

    第二个新的是“新的位置”。它执行初始化(即调用任何必要的构造函数),而不进行任何分配。当需要创建自定义内存分配方案时,它非常有用。

        4
  •  3
  •   Loki Astari    15 年前

    这是新位置。


    它通常用于构建缓冲区,然后在其中构建其他类型。

    // Allocate a buffer with enough room for two T objects.
    char* buffer   = new char[sizeof(T) * 2];
    
    // Allocate a T in slot zero
    T* t1 = new (buffer + 0 * sizeof(T)) T("Zero");
    
    // Allocate a T in slot one
    T* t2 = new (buffer + 1 * sizeof(T)) T("One");
    

    这是最基本的。
    但是请记住,分配了新位置的对象 不能 delete 陈述。这是因为 删除 尝试回收由分配的内存 new

    t1->~T();
    t2->~T();
    

    别忘了删除原始缓冲区。

    delete [] buffer;
    

    其他一些注意事项:
    人们经常看到缓冲区可以在堆栈上实现,因此可以自动释放

    char buffer[sizeof(T) * 2];
    

    不幸的是,这在技术上是可以的(它可以编译)。但是,由于缓冲区的内存可能没有正确对齐以放置T,因此不能保证它能正常工作。因此,必须动态地分配缓冲区(通过使用新的it保证内存与所分配大小的任何对象正确对齐(因此,通过扩展,它也与小于所分配大小的任何大小对齐)。解决这个问题的简单方法是使用std::vector

    std::vector<char>    buffer(sizeof(T) * 2);
    T* t1 = new (&buffer[0] + 0 * sizeof(T)) T("Zero");
    T* t2 = new (&buffer[0] + 1 * sizeof(T)) T("One");
    

    placement new的另一个用途是重置对象。

    T   obj1("Plop");
    obj1  = T("Another Plop");
    
    // Can be done like this:
    T   obj1("Plop");
    obj1.~T();
    new (&obj1) T("Another Plop");   // Seems excessive to me. But can be us-full
                                     // in some extreme situations.
    

    记住,如果使用reset方法,必须先销毁旧对象(否则该对象可能无法正常工作)。

        5
  •  2
  •   bjskishore123    15 年前
    int * y = new (x) int; 
    

    编辑:除了自定义分配,placement new还有助于 重新初始化

    class Test
    {
        int startVal;
    public:
        Test()
        {
            startVal = 1;
        }
        void setVal(int val) { startVal = val; }
    };
    int main()
    {
        Test *p = new Test;  //Creates new object and initializes it with
                              //a call to constructor.
        p->setVal(10);  //Change object content.
        new(p) Test; //Reset object:
        //object pointed by p will be re-initialzed here by making
        //a call to constructor. startVal will be back to 1
    }
    

    如上所述,也可以使用placement new实现对象状态重置。 placement new不分配内存,它在paranthesis中的指定地址构造对象。