关于移动/复制c++;对象实例 我试图在C++中创建一个类型无关的向量,它是用两个东西来区分的。首先,它在对象本身中分配内存,至少直到某一点,而不是在堆上维护对象的实际数组。其次,它不能使用C++的复制/分配构造函数,这似乎会减慢代码的速度,而且是不必要的

关于移动/复制c++;对象实例 我试图在C++中创建一个类型无关的向量,它是用两个东西来区分的。首先,它在对象本身中分配内存,至少直到某一点,而不是在堆上维护对象的实际数组。其次,它不能使用C++的复制/分配构造函数,这似乎会减慢代码的速度,而且是不必要的,c++,C++,在查看我在计算机上维护的代码库时,我在LLVM的代码库中发现了一个类,它非常完美地描述了我要查找的内容:。对于C++来说,是比较新的,我不完全清楚为什么做出一些设计决定。例如,为什么数组是按U而不是T分配的?该评论提供了一个线索: 如果T有一个ctor或dtor,我们不希望它自动运行,所以我们需要将空间表示为其他内容。char数组可以很好地工作,但可能没有充分对齐。相反,我们为空间使用一些联合实例,这保证了最大对齐 当然,U指的是以下联合体: union U { double D;

在查看我在计算机上维护的代码库时,我在LLVM的代码库中发现了一个类,它非常完美地描述了我要查找的内容:。对于C++来说,是比较新的,我不完全清楚为什么做出一些设计决定。例如,为什么数组是按
U
而不是
T
分配的?该评论提供了一个线索:

如果T有一个ctor或dtor,我们不希望它自动运行,所以我们需要将空间表示为其他内容。char数组可以很好地工作,但可能没有充分对齐。相反,我们为空间使用一些联合实例,这保证了最大对齐

当然,
U
指的是以下联合体:

union U {
    double D;
    long double LD;
    long long L;
    void *P;
} FirstEl;
所以,我想,这里是我真正的问题:为什么分配
T
数组意味着调用构造函数/析构函数?有没有方法可以移动C++对象实例,即在向量中进出,而不调用这些构造函数/析构函数?我想我可以使用LLVM的
SmallVector
实现,但我讨厌在不理解它的情况下使用代码

最好的, 杜安

为什么分配一个T数组意味着调用构造函数/析构函数

因为这是标准规定的。分配一个
T
数组也意味着初始化它的每个元素。请注意,在C++11中,
char
的对齐限制已更改,因此现在“char数组工作得很好”

有没有办法将C++对象实例围绕着,即在向量中进出,而不调用这些构造函数/析构函数?


是的,通过移动构造函数/赋值操作符,这也是C++11的新功能。C++03有一个仿真器库,还可以在Boost

移动支持容器。您应该看看标准库分配器背后的基本机制,它可以处理您可能遇到的许多问题

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

// 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();
为了实现您的想法,您可以使用我使用的char数组
q
,并使其成为您的类的成员。也就是说,类总是随身携带一些用于构造对象的内存

实际对象构造是使用全局放置新表达式完成的。回想一下,这样构造的对象必须手动销毁(这是您的责任)

标准库分配器做的差不多就是这样

分离内存分配和对象构造是任何一种高级内存管理和责任类的核心


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

C++11还具有移动语义。如果在类中实现一个move构造函数(比如Foo),std::vector的性能会更好

C++的复制/分配构造函数,这似乎减慢了代码的速度…
它生成正确的代码,因为它们是必需的。有几个类如果被memcopy,并且没有默认构造函数,就会崩溃。注意:动态分配的char数组适用于所有对齐。自动字符数组可能不会。