C++ 使用指针移动构造函数(*&&&语法)
C++ Move Constructor With Pointers (*&& Syntax)
我想知道C++中的构造<type>*&&
是否有任何问题。让我举一个具体的例子。
假设我们有一个类,它应该由数组构造而成。我们通常会这样做:
class Things
{
public:
Things(const ThingType* arrayOfThings, int sizeOfArray)
: myArray(new ThingType[sizeOfArray])
{
for (int i = 0; i < sizeOfArray; i++)
myArray[i] = arrayOfThings[i];
}
private:
ThingType* myArray;
}
如果我们想保留arrayOfThings
,这很好,因为我们正在对其进行深度复制。此外,通过使用const
,我们确保它不会在构造函数中被修改。
但假设我们的程序有很多这样的语句:
Things myThings(new ThingType[9001] {thing_0, ... , thing_9000}, 9001);
这可能看起来很奇怪,但可能会发生巨大的ThingType
数组作为右值从函数返回的情况。
在这种情况下,我们不关心保留作为参数传递的指针。事实上,我们绝对不想对其进行深入复制,因为保存我们无论如何都要销毁的东西将是一种巨大的时间浪费。
一个可能的解决方案是添加另一个构造函数来处理非常量右值ThingType
指针的情况,就像普通的move构造函数处理类的非常量右价实例的情况一样:
public:
Things(ThingType*&& arrayOfThings, int sizeOfArray)
: myArray(arrayOfThings)
{
arrayOfThings = NULL;
}
这似乎解决了我的问题,但我没有发现上面看到的关于<type>*&&
结构的太多信息。这是犹太洁食吗,还是我会因为混合指针和引用而被送到地下城?
经过一段时间后,我相信我找到了令人满意的解决方案,尽管远非最佳解决方案。由于没有人回答这个问题,我将分享我找到的最佳解决方案。
正如Justin所指出的,当我们在构造函数调用中获取ThingType
变量的地址(而不是ThingType
指针的地址,正如他在回答中所暗示的那样)时,使用ThingType*&&
可能会带来麻烦。
如果t
是ThingType
,则表达式&t
是类型为ThingType*
的r值,因此Thing myThing(&t, ...)
将调用move构造函数,结果使myThing.myArray
指向t
。在大多数情况下,这不是我们想要的。
一种解决方案是使用矢量而不是阵列,如下所示:
// Copy
explicit Things(const std::vector<ThingType>& vectorOfThings)
: myVector(vectorOfThings)
{ }
// Move
explicit Things(std::vector<ThingType>&& vectorOfThings)
: myVector(std::move(vectorOfThings))
{ }
move构造函数将用于以下情况:
Things myThings(vector<ThingType>{thing_0, ... , thing_9000});
虽然这解决了问题,但如果我们依赖于返回原始指针的API,或者如果我们不想放弃数组,这是不可行的。在这种情况下,我们可以使用智能指针来解决问题。
假设,我们有一个函数ThingType* generateArray()
,我们想用它来初始化Things
类型的对象。我们应该做的第一件事是用另一个返回智能指针的函数来包装这个函数。
unique_ptr<ThingType[]> generateSmartPointer()
{
return unique_ptr<ThingType[]>(generateArray());
}
在这里,我使用了unique_pointer
,但这可能会根据实现而改变。
现在,我们向Things
添加一个新的构造函数,并将unique_ptr
的实例作为参数。这将充当ThingType
:数组的移动构造函数
Things(unique_ptr<ThingType[]> thingsPointer, int sizeOfArray)
: myArray(thingsInput.release()), size(sizeOfArray)
{ }
unique_ptr<T>.release()
用于获取数组,同时使唯一指针释放对它的所有权,防止唯一指针一旦被破坏就被删除。
就是这样。这是我发现的解决这个问题的两个最好的解决方案,虽然它们还远远不够完美,但到目前为止,考虑到每次实施的目标,它们都行之有效。
- 使用基类指针调用基类的值构造函数的语法是什么?
- 将值传递给构造函数 c++ 的差异语法
- 没有数据成员和大括号语法的类的默认复制构造函数
- 此语法中的构造函数转换错误
- 返回语句中的构造函数语法
- 复制构造函数语法错误:myclass 没有成员 mymember
- 在 c++ 中移动 2d 数组的构造函数(语法逻辑不清楚):
- C++类构造函数语法的解释
- C++ 使用指针移动构造函数(*&&&语法)
- C++构造函数中的语法错误 - arugment 是对另一个类中的对象的引用
- 复制构造函数语法并显示构造函数的值
- 了解构造函数初始值设定项列表中带有大括号的奇怪语法
- 什么是正确的语法,用于在Visual Studio C 中贬低单个构造函数
- 带有分配过载语法的复制构造函数
- 构造函数主体中的简单指针语法出现问题
- 带有const成员的构造函数的语法
- 在私有类语法中复制构造函数
- 在构造函数成员初始化之前调用成员函数的语法
- C++ - 在构造函数中使用引用时出现语法错误
- 在语法构造函数中评估的语义操作(或不评估?