关于移动/复制c++对象实例
On moving/copying c++ object instances
我试图在c++中创建一个类型无关的向量,它有两个区别。首先,它在对象本身中分配内存,至少直到某一点,而不是在堆上维护实际的对象数组。其次,它不能使用c++的复制/赋值构造函数,这似乎会减慢代码的速度,而且是不必要的。
在查看我在计算机上维护的代码库时,我在LLVM的代码库中发现了一个类,它非常完美地描述了我正在寻找的东西:SmallVector.h。作为c++的新手,我不完全确定为什么要做出一些设计决策。例如,为什么数组是按U
而不是按T
分配的?注释给出了一个提示:
如果T有一个tor或dr,我们不希望它自动运行,所以我们需要用其他东西来表示空间。char数组可以很好地工作,但可能没有充分对齐。相反,我们为空间使用一定数量的联合实例,这保证了最大的对齐。
U
,当然是指以下并集:
union U {
double D;
long double LD;
long long L;
void *P;
} FirstEl;
所以,我猜,这是我真正的问题:为什么分配T
数组意味着调用构造函数/析构函数?有没有办法移动c++对象实例,即进出矢量,而不调用这些构造函数/析构函数?我想我可以使用LLVM的SmallVector
实现,但我讨厌在不理解它的情况下使用代码。
最好的,杜安
您应该看看标准库分配器背后的基本机制,它可以处理您可能遇到的许多问题!
这是基本的分配原则。我们将内存分配和对象构造分开。正如您所观察到的,最大的障碍是内存应该为对象正确对齐:
// 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
,并使它成为你的类的成员。也就是说,类总是携带一些内存来构造对象。
实际的对象构造是使用全局place -new表达式完成的。回想一下,这样构造的对象必须手动销毁(这将是您的责任)。
标准库分配器做了类似的事情。
分离内存分配和对象构造是任何高级内存管理和责任归属类的核心。
注意,一旦在特定地址构造了对象,就不能移动周围的内存。对象很可能取决于它在内存中的位置!移动对象的唯一有效方法是复制/移动-构造一个新对象。
为什么分配数组T意味着调用构造函数/析构函数?
因为这是标准要求的。分配一个T
数组意味着初始化它的每个元素。请注意,在c++ 11中,char
的对齐限制已经改变,因此现在"一个char数组工作得很好"。
是否有任何方法移动c++对象实例,即进出向量,而不调用这些构造函数/析构函数?
可以,通过move构造函数/赋值操作符实现,这也是c++ 11的新特性。在Boost
c++ 11也有移动语义。如果在类中实现移动构造函数(比如Foo), std::vector的性能会好得多。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 使lambda不可复制/不可移动