代码之家  ›  专栏  ›  技术社区  ›  Scottie T

C++构造“放置新”的用途是什么?

  •  12
  • Scottie T  · 技术社区  · 16 年前

    我刚刚了解了C++构造,称为“放置新”。它允许您精确地控制指针指向内存的位置。看起来是这样的:

     #include <new>        // Must #include this to use "placement new"
     #include "Fred.h"     // Declaration of class Fred
    
     void someCode()
     {
       char memory[sizeof(Fred)];
       void* place = memory;
    
       Fred* f = new(place) Fred();   // Create a pointer to a Fred(),
                                      // stored at "place"
    
       // The pointers f and place will be equal
    
       ...
     } 
    

    (示例来自 C++ FAQ Lite )

    在本例中, this 弗雷德的指针等于 place .


    我在我们团队的代码中见过一两次。根据你的经验,这个结构能实现什么?其他指针语言有类似的结构吗?对我来说,它似乎让人想起 equivalence 在fortran语言中,它允许不同的变量在内存中占据相同的位置。

    12 回复  |  直到 16 年前
        1
  •  15
  •   David Thornley    16 年前

    它允许您自己进行内存管理。通常这会让你在最好的表现略有改善,但有时这是一个巨大的胜利。例如,如果您的程序正在使用大量标准大小的对象,您可能希望创建一个具有一个大内存分配的池。

    这类工作也在C中完成,但由于C中没有构造函数,因此不需要任何语言支持。

        2
  •  12
  •   Nemanja Trifunovic    16 年前

    它还用于嵌入式编程,其中IO设备通常映射到特定的内存地址

        3
  •  7
  •   Greg Rogers    16 年前

    我在共享内存段中构造对象时使用过它。

        4
  •  7
  •   Loki Astari    16 年前

    在构建自己的容器类对象时很有用。

    例如,如果要创建向量。如果为大量对象保留空间,则需要使用不调用对象构造函数的方法(如new char[sizeof(object)*reservesize])分配内存。然后当人们开始向向量中添加对象时,使用placement new将它们复制到分配的内存中。

    template<typename T>
    class SillyVectorExample
    {
        public:
            SillyVectorExample()
                :reserved(10)
                ,size(0)
                ,data(new char[sizeof(T) * reserved])
            {}
            void push_back(T const& object)
            {
                if (size >= reserved)
                {
                    // Do Somthing.
                }
                // Place a copy of the object into the data store.
                new (data+(sizeof(T)*size))  T(object);
                ++size;
            }
            // Add other methods to make sure data is copied and dealllocated correctly.
        private:
            size_t   reserved;
            size_t   size;
            char*    data;
     };
    

    另外,我不主张这样做。这只是容器如何工作的一个简化示例。

        5
  •  5
  •   James Hopkin    16 年前

    Placement New可用于创建类型安全联合,如Boost variant .

    union类包含的缓冲区大小与它指定要包含的最大类型一样大(并且具有足够的对齐方式)。资讯科技置放 new 根据需要将对象放入缓冲区。

        6
  •  4
  •   Edouard A.    16 年前

    在内核模式下执行C++时,我使用这个构造。

    我使用内核模式内存分配器并在分配的块上构造对象。

    所有这些都被封装在类和函数中,但最后我做了一个新的布局。

        7
  •  4
  •   Drew Hall    16 年前

    Placement New不是要使指针相等(您可以使用赋值!).

    Placement New用于在特定位置构造对象。在C++中构造对象有三种方法,而放置new是唯一一种可以明确控制对象在何处“生存”的方法。这对于一些事情很有用,包括共享内存、低级设备I/O和内存池/分配器实现。

    通过堆栈分配,对象被构造在堆栈的顶部,不管它现在在哪里。

    使用“regular”new,对象将在标准库管理的堆上的有效任意地址处构造(除非重写了operator new)。

    Placement New说“在这个地址专门为我构建一个对象”,它的实现只是一个重载的运算符New,它返回传递给它的指针,作为到达新运算符的剩余机器的一种方法,后者在返回的内存中构造一个对象。操作员新功能。

    值得注意的是,运算符new函数可以重载任意参数(就像任何其他函数一样)。这些其他参数通过“new(arg 2,arg3,…,argn)”语法传递。arg1总是隐式地传递为“sizeof(无论您正在构造什么)”。

        8
  •  2
  •   Uri    16 年前

    通过控制精确的位置,可以将内存中的内容对齐,这可以 有时 用于提高CPU获取/缓存性能。 但从未真正看到它在使用

        9
  •  1
  •   Tommy Herbert    16 年前

    当将内存调出到硬盘上的文件时,它可能很有用,当操作大型对象时可能会这样做。

        10
  •  1
  •   Vinay    16 年前

    Placement New允许开发人员从预先分配的内存块中分配内存。如果系统较大,则开发人员会使用Placement New。现在我正在研究一个更大的航空电子软件,我们在那里分配一开始执行应用程序所需的大内存。我们使用新的布局来分配内存。它将性能提高到一定程度。

        11
  •  0
  •   hasen    16 年前

    在我看来,这是一种在堆栈上分配对象的方法。

        12
  •  0
  •   Steve Fallows    16 年前

    我用它来创建基于包含从网络接收的消息的内存的对象。

    推荐文章