c++ - 关于移动/复制 C++ 对象实例

标签 c++

我正试图在 C++ 中创建一个类型不可知的 vector ,它有两个特点。首先,它在对象本身中分配内存,至少在某一点之前,而不是在堆上维护实际的对象数组。其次,它不能使用 C++ 的复制/分配构造函数,这似乎会减慢代码速度并且没有必要。

在查看我在计算机上维护的代码库时,我在 LLVM 的代码库中找到了一个类,它几乎完美地描述了我正在寻找的内容:SmallVector.h .作为 C++ 的新手,我不完全确定为什么要做出某些设计决策。例如,为什么数组是根据 U 而不是 T 分配的?评论给出了线索​​:

If T has a ctor or dtor, we don't want it to be automatically run, so we need to represent the space as something else. An array of char would work great, but might not be aligned sufficiently. Instead we use some number of union instances for the space, which guarantee maximal alignment.

U,当然是指下面的并集:

union U {
    double D;
    long double LD;
    long long L;
    void *P;
} FirstEl;

所以,我想,这是我真正的问题:为什么分配 T 数组意味着调用构造函数/析构函数?有没有什么方法可以在不调用这些构造函数/析构函数的情况下移动 C++ 对象实例,即进出 vector ?我想我可以只使用 LLVM 的 SmallVector 实现,但我讨厌在不理解代码的情况下使用它。

最好的, 杜安

最佳答案

您应该看看标准库分配器 背后的基 native 制,它处理了您可能遇到的许多问题!

这是基本的分配原则。我们将内存分配和对象构造分开。正如您所观察到的,最大的障碍是内存应该针对对象正确对齐:

// getting memory
void * p = malloc(1000);  // version 1, system's allocator
char q[1000];             // automatic array, this is also memory :-)

// constructing an object
T * m_x1 = ::new (p) T;   // default-initialized
T * m_x2 = ::new (q) T(); // value-initialized
T * m_x3 = ::new (q + sizeof(T)) T(1, 'a'); // some specific constructor

// destroying the objects:
m_x1->~T();
m_x2->~T();
m_x3->~T();

要按照您的想法进行操作,您可以采用我使用的字符数组 q 并使其成为您类(class)的成员。也就是说,该类始终带有一些用于构造对象的内存。

实际的对象构建是通过全局 placement-new 表达式完成的。回想一下,这样构造的对象必须手动销毁(这是您的责任)。

标准库分配器的作用与此类似。

分离内存分配和对象构造是任何类型的高级内存管理、责任归属类的核心。

请注意,一旦在特定地址构造了对象,您不得移动内存。该对象很可能取决于它在内存中的位置!移动对象的唯一有效方法是复制/移动构造一个新对象。

关于c++ - 关于移动/复制 C++ 对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7988737/

相关文章:

c++ - 自调整列表和常规链表之间的主要区别

c++ - 如何在 std::string 和 Aws::String 之间进行转换?

c++ - 将端口地址传递给函数

c++ - 在 C++ 中初始化对象数组时出错

php - 强制类型 SWIG

c++ - 使用 GMOCK 模拟具有私有(private)构造函数的类

用于 XML-RPC 的 C++ 库

c++ - FLTK桌面截图问题

c++ - 与编译时未解析的字符串文字进行比较

c++ - pthread 库的条件变量示例