标签: move-constructor

将 std::move shared_ptr 与条件运算符一起使用时的奇怪行为

我正在使用std::moveon编写一些 C++ 代码shared_ptr,并得到了非常奇怪的输出。我简化了我的代码如下

int func(std::shared_ptr<int>&& a) {
    return 0;
}

int main() {
    std::shared_ptr<int> ptr = std::make_shared<int>(1);

    for (int i = 0; i != 10; ++i) {
        func(i == 9 ? std::move(ptr) : std::shared_ptr<int>(ptr));
    }

    if (ptr) {
        std::cout << "ptr is not null: " << *ptr << "\n";
    } else {
        std::cout << "ptr is null\n";
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了输出

ptr is null
Run Code Online (Sandbox Code Playgroud)

正如我所预期的,我的ptrwill 在最后一个循环中被移动(转换为std::shared_ptr<int>&&),并且由于func从不窃取 中的内存a,所以我的 …

c++ conditional-operator shared-ptr move-constructor move-semantics

5
推荐指数
1
解决办法
153
查看次数

移动构造函数矫枉过正

我有一个类,它包含一个指向大块已分配内存和许多基本类型成员的指针.我正在考虑移动构造函数,并认为这是一个使用它的绝佳机会.显然,如果对于基元是一个好主意,指针应该移动但是idk.

以下是该课程的一个人为设想的例子:

class Foo {
private:
  long m_bar = 1;
  /* 20+ similar members */
};
Run Code Online (Sandbox Code Playgroud)

为了使它们可移动,必须动态分配它们.

class Foo {
public:
  Foo(Foo && rhs) : m_bar(rhs.m_bar) { rhs.m_bar = nullptr; }
  ~Foo() { delete m_bar; }
private:
  long *m_bar = new long{1};
};
Run Code Online (Sandbox Code Playgroud)

我的问题是,分配在堆上的开销是否会使移动语义引入的性能增加无效?

c++ move-constructor move-semantics c++11

4
推荐指数
1
解决办法
1175
查看次数

按值返回时强制执行RVO /移动构造

假设我有一个带有复制构造函数和移动构造函数的对象'foo',以及一个函数

foo f() {
    foo bar;
    /* do some work */
    return bar;
}
Run Code Online (Sandbox Code Playgroud)

该标准似乎表明编译器将尝试执行:NRVO,通过r值ref返回,按值返回,失败; 以该顺序.

有没有办法强制编译器永远不会按值返回,因为我的复制构造函数非常昂贵?

c++ rvalue-reference move-constructor return-value-optimization c++11

4
推荐指数
1
解决办法
703
查看次数

如何将unique_ptr用于数组

我上课了

class A {
public:
  A(){cout<<"C";}
  ~A(){cout<<"D";}
};
int main(){
  unique_ptr<A> a(new A[5]); // - doesn't work 
  unique_ptr<A> a(new A[1]); // - doesn't work
  unique_ptr<A> a(new A); // - works
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

我想这是关于移动构造函数(由于析构函数不能自动创建),但为什么我们需要一个移动构造函数呢?

有什么区别:

unique_ptr<A> a(new A[1]); // - doesn't work
unique_ptr<A> a(new A); // -works
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr move-constructor

4
推荐指数
1
解决办法
104
查看次数

移动涉及const unique_ptr的构造函数

在下面的代码中,我创建了p const,因为在Foo的生命周期中它永远不会指向任何其他int.这不会编译,因为调用了unique_ptr的复制构造函数,这显然已被删除.除了使p非常数之外还有其他解决方案吗?谢谢.

#include <memory>

using namespace std;

class Foo 
{
public:
  //x is a large struct in reality
  Foo(const int* const x) : p(x) {};
  Foo(Foo&& foo) : p(std::move(foo.p)) {};
private:
  const unique_ptr<int> p;
};
Run Code Online (Sandbox Code Playgroud)

c++ const move unique-ptr move-constructor

4
推荐指数
1
解决办法
7142
查看次数

最佳C++移动构造函数实现实践

我试图理解move-constructor的实现.我们都知道如果我们需要管理C++类中的资源,我们需要实现五阶规则(C++编程).

微软给我们举了一个例子:https://msdn.microsoft.com/en-us/library/dd293665.aspx

这是更好的一个,它使用copy-swap来避免代码重复: 动态分配一个对象数组

     // C++11
     A(A&& src) noexcept
         : mSize(0)
         , mArray(NULL)
     {
         // Can we write src.swap(*this);
         // or (*this).swap(src);
         (*this) = std::move(src); // Implements in terms of assignment
     }
Run Code Online (Sandbox Code Playgroud)

在move-constructor中,直接:

         // Can we write src.swap(*this);
         // or (*this).swap(src);
Run Code Online (Sandbox Code Playgroud)

因为我觉得(*this) = std::move(src)有点复杂.因为如果我们(*this) = src无意中写,它会调用普通赋值运算符而不是move-assignment-operator.

除了这个问题,在微软的例子中,他们编写了这样的代码:在move-assignment-operator中,我们是否需要检查自我赋值?有可能发生吗?

// Move assignment operator.
MemoryBlock& operator=(MemoryBlock&& other)
{
   std::cout << "In operator=(MemoryBlock&&). length = " 
             << other._length << "." << std::endl;

   if (this != &other)
   { …
Run Code Online (Sandbox Code Playgroud)

c++ move move-constructor c++11

4
推荐指数
2
解决办法
2477
查看次数

C++为什么我不能在具有已删除的默认构造函数的对象上使用swap

我正在尝试为使用类Id的对象A实现移动构造函数.类Id是自动生成的,为了将来的编码健全,我选择在我这样做时删除默认构造函数.

然而,当我尝试在A的移动构造函数中使用swap时,它抱怨Id默认构造函数被删除.我认为交换不是构造任何新对象,而只是交换两个项目的地址.

我是否误解了它,它实际上是在创建第三个临时实例?

如果是这种情况,下面实现移动构造函数的最佳方法是什么?

我在下面列出了一个最小的例子:

class Id {

public:
    Id() = delete;
    Id(std::string id) : m_id(id) {}

private:
    std::string m_id;
};

class A {

public:
    A() = delete;
    A(Id id) : m_id(id) {}


    A(A&& other) {
        std::swap(m_id, other.m_id);
    }

private:
    Id m_id;
};
Run Code Online (Sandbox Code Playgroud)

编译器返回以下错误:

In constructor 'A::A(A&&)':
21:18: error: use of deleted function 'Id::Id()'
8:5: note: declared here
In file included from /usr/include/c++/4.9/bits/stl_pair.h:59:0,
                 from /usr/include/c++/4.9/bits/stl_algobase.h:64,
                 from /usr/include/c++/4.9/bits/char_traits.h:39,
                 from /usr/include/c++/4.9/ios:40,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 2:
/usr/include/c++/4.9/bits/move.h: …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue default-constructor move-constructor move-semantics

4
推荐指数
1
解决办法
348
查看次数

与移动构造函数混淆:无法调用移动构造函数

我在使用C++理解移动构造函数时遇到了困难.我用默认构造函数,复制构造函数,移动构造函数和析构函数创建了一个简单的类.此外,我已经定义了一个具有两个重载的函数,一个接受对该类的引用,另一个接受对该类的右值引用.我的测试代码如下.

#include <iostream>


class c {

public:

    c() {
        std::cout << "default constructor" << std::endl;
    }

    c(const c& s) {
        std::cout << "copy constructor" << std::endl;
    }

    c(c&& s) {
        std::cout << "move constructor" << std::endl;
    }

    ~c() {
        std::cout << "destructor" << std::endl;
    }

};

void f(c& s) {
    std::cout << "passed by reference" << std::endl;
}

void f(c&& s) {
    std::cout << "passed by rvalue reference" << std::endl;
}

int main() {

    c s1; // line 1
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference most-vexing-parse move-constructor move-semantics

4
推荐指数
2
解决办法
421
查看次数

c ++ copy constructor vs std :: vector的move构造函数

我有一个std::vector类似的课程

struct Mystruct
{
  Mystruct(const std::vector<int>& w): v(w) 
  {
    std::cout << "Copy constructor :" << v.at(0) << "\n";
  }
  Mystruct(const std::vector<int>&& w): v(w)
  {
    std::cout << "Move Constructor :" << v.at(0) << "\n";
  }
  private:
  std::vector<int> v;
};
Run Code Online (Sandbox Code Playgroud)

我创建像这样的对象

int main() 
{
  auto x = std::vector<int> {1,2,3};
  Mystruct M1(x);
  Mystruct M2(std::vector<int> {3,2,1});
  return 0; 
}
Run Code Online (Sandbox Code Playgroud)

M1使用复制构造函数和M2使用"移动"构造函数构造,但是在gdb中运行时,两个分配都为v和w保留不同的地址,如果我在初始化列表中使用v(std :: move(w)),则会发生同样的情况.第二个构造函数.所以我猜两个人都在复制w的内容,这是正确的吗?如果是这种情况,我怎样才能移动w的内容而不是复制它们

c++ copy-constructor move-constructor

4
推荐指数
1
解决办法
3656
查看次数

C++ 编译器何时推断方法的 noexcept ?

我只是注意到我的一个std::vector<Foo>在调整大小时正在复制而不是移动它的元素 - 即使Foo有一个移动 ctor:

class Foo {
    // ...
    Foo(Foo&& other) : id_(other.id_), ptr_(other.ptr_), flag(other.flag)
    {
        other.flag = false;
    };
    // ...
    int   id_; 
    void* ptr_; 
    bool  flag;
}
Run Code Online (Sandbox Code Playgroud)

然后我读到:

在 std::vector 上调整大小不会调用移动构造函数

这提醒我,std::vector只有在声明了元素的移动构造函数时才会使用移动构造noexcept。当我添加时noexcept,会调用移动 ctor。

我的问题是:为什么,给定移动 ctor 的代码,编译器没有确定它是noexcept?我的意思是,它可以知道不能抛出异常的事实。此外,推断是否noexcept被标准禁止,或者不是由我的特定编译器完成的?

我在 GNU/Linux 上使用 GCC 5.4.0。

c++ gcc compiler-optimization move-constructor noexcept

4
推荐指数
1
解决办法
149
查看次数