首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++用指针移动构造函数(*&&语法)

C++用指针移动构造函数(*&&语法)
EN

Stack Overflow用户
提问于 2017-10-26 18:18:30
回答 1查看 567关注 0票数 0

我想知道在<type>*&& in C++中是否存在任何问题。让我举一个具体的例子。

假设我们有一个应该由数组构造的类。我们通常会这样做:

代码语言:javascript
复制
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,我们可以确保它不会在构造函数中被修改。

但假设我们的程序有很多这样的语句:

代码语言:javascript
复制
Things myThings(new ThingType[9001] {thing_0, ... , thing_9000}, 9001);

这可能看起来很奇怪,但可能会发生这样的情况,即从函数作为rvalue返回巨大的ThingType数组。

在这种情况下,我们不关心保存作为参数传递的指针。事实上,我们绝对不希望做一个深刻的拷贝,因为它将是巨大的浪费时间来保存我们将要摧毁的东西。

一种可能的解决方案是添加另一个构造函数来处理非const值ThingType指针的情况,就像一般移动构造函数处理类的非const值实例的情况一样:

代码语言:javascript
复制
public:
     Things(ThingType*&& arrayOfThings, int sizeOfArray) 
            : myArray(arrayOfThings)
         {
              arrayOfThings = NULL;                  
         }

这似乎解决了我的问题,但我并没有找到上面看到的关于<type>*&&结构的多少信息。它是犹太的,还是我会被送去地牢混合指针和推荐信?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-14 14:00:36

过了一段时间,我相信我找到了满意的--尽管不是最优的--解。由于没有人回答这个问题,我将分享我找到的最好的解决办法。

正如贾斯汀所指出的那样,当我们在构造函数调用中使用ThingType变量的地址(但不是ThingTypeThingType指针的地址,他在答案中暗示的)时,使用ThingType可能会带来麻烦。

如果tThingType,则表达式&tThingType*类型的r值,因此Thing myThing(&t, ...)将调用移动构造函数,结果是使myThing.myArray指向t。在大多数情况下,这不是我们想要的。

一种解决方案是使用向量而不是数组,如下所示:

代码语言:javascript
复制
// Copy
explicit Things(const std::vector<ThingType>& vectorOfThings) 
            : myVector(vectorOfThings)
         {  }

// Move
explicit Things(std::vector<ThingType>&& vectorOfThings) 
        : myVector(std::move(vectorOfThings))
         {  }

然后,会在如下情况下使用移动构造函数:

Things myThings(vector<ThingType>{thing_0, ... , thing_9000});

虽然这解决了这个问题,但是如果我们依赖于返回原始指针的API,或者如果我们不想放弃数组,则是不可行的。在这种情况下,我们可以使用智能指针来解决问题。

假设我们有一个函数ThingType* generateArray(),我们希望用它来初始化Things类型的对象。我们应该做的第一件事是用另一个函数包装这个函数,这个函数返回一个智能指针。

代码语言:javascript
复制
unique_ptr<ThingType[]> generateSmartPointer()
{
  return unique_ptr<ThingType[]>(generateArray());
}

这里我使用了一个unique_pointer,但是这可能会根据实现的不同而改变。

现在,我们向Things添加一个新的构造函数,并以unique_ptr实例作为参数。这将充当ThingType数组的移动构造函数。

代码语言:javascript
复制
Things(unique_ptr<ThingType[]> thingsPointer, int sizeOfArray) 
        : myArray(thingsInput.release()), size(sizeOfArray)
         {  }

unique_ptr<T>.release()用于获取数组,同时使惟一指针释放它的所有权,防止在唯一指针被破坏后数组被删除。

就是这样。这是我对这个问题找到的两个最好的解决办法,虽然它们远非十全十美,但迄今为止,它们一直在考虑每项执行的目标。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46961226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档