标签: move-constructor

C++ 11右值引用也调用了拷贝构造函数

我一直在测试一些C++ 11的一些功能.我遇到了r值引用并移动构造函数.

我实现了我的第一个移动构造函数,这里是:

#include <iostream>
#include <vector>
using namespace std;

class TestClass{

public:
    TestClass(int s):
        size(s), arr(new int[s]){
    }
    ~TestClass(){
        if (arr)
            delete arr;
    }
    // copy constructor
    TestClass(const TestClass& other):
            size(other.size), arr(new int[other.size]){
        std::copy(other.arr, other.arr + other.size, arr);
    }

    // move constructor
    TestClass(TestClass&& other){
        arr=other.arr;
        size=other.size;

        other.arr=nullptr;
        other.size=0;
    }

private:
    int size;
    int * arr;
};

int main(){
    vector<TestClass> vec;

    clock_t start=clock();
    for(int i=0;i<500000;i++){
        vec.push_back(TestClass(1000));
    }
    clock_t stop=clock();
    cout<<stop-start<<endl;

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

代码工作正常.无论如何把一个std :: cout放在复制构造函数中我注意到它被调用了!并且很多次..(移动构造函数500000次,复制构造函数524287次).

让我感到惊讶的是,如果我从代码中注释掉复制构造函数,整个程序会更快,而这次移动构造函数被称为1024287次.

任何线索?

c++ rvalue-reference move-constructor c++11

24
推荐指数
2
解决办法
2978
查看次数

显式移动构造函数?

explicit对于可以使用一个参数调用的所有 大多数构造函数,建议使用该关键字,但复制构造函数除外.

对于复制构造函数,它有一个用途(禁止通过函数调用,返回等隐式复制),但它不是通常想要的.

移动构造函数怎么样?是否有任何合理的用例使它们明确?这里的好习惯是什么?

c++ explicit-constructor move-constructor c++11

23
推荐指数
3
解决办法
4202
查看次数

何时调用Move Constructor?

我很困惑何时调用移动构造函数与复制构造函数.我已经阅读了以下资料:

移动构造函数未在C++ 0x中调用

在C++ 11中移动语义和右值引用

MSDN

所有这些来源要么过于复杂(我只想要一个简单的例子),要么只展示如何编写移动构造函数,而不是如何调用它.我写了一个简单的问题更具体:

const class noConstruct{}NoConstruct;
class a
{
private:
    int *Array;
public:
    a();
    a(noConstruct);
    a(const a&);
    a& operator=(const a&);
    a(a&&);
    a& operator=(a&&);
    ~a();
};

a::a()
{
    Array=new int[5]{1,2,3,4,5};
}
a::a(noConstruct Parameter)
{
    Array=nullptr;
}
a::a(const a& Old): Array(Old.Array)
{

}
a& a::operator=(const a&Old)
{
    delete[] Array;
    Array=new int[5];
    for (int i=0;i!=5;i++)
    {
        Array[i]=Old.Array[i];
    }
    return *this;
}
a::a(a&&Old)
{
    Array=Old.Array;
    Old.Array=nullptr;
}
a& a::operator=(a&&Old)
{
    Array=Old.Array;
    Old.Array=nullptr;
    return *this;
}
a::~a()
{
    delete[] Array;
} …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor c++11

23
推荐指数
2
解决办法
2万
查看次数

移动构造函数是否在C++中调用了两次?

看看这段代码:

class Foo
{
public:

    string name;

    Foo(string n) : name{n}
    {
        cout << "CTOR (" << name << ")" << endl;
    }

    Foo(Foo&& moved)
    {
        cout << "MOVE CTOR (moving " << moved.name << " into -> " << name << ")" << endl;

        name = moved.name + " ###";
    }

    ~Foo()
    {
        cout << "DTOR of " << name << endl;
    }
};

Foo f()
{
    return Foo("Hello");
}

int main()
{
    Foo myObject = f();

    cout << …
Run Code Online (Sandbox Code Playgroud)

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

23
推荐指数
2
解决办法
1567
查看次数

如何使用移动构造函数获取g ++来编译c ++ 11代码?

我似乎无法使用g ++来编译使用移动构造函数的c ++ 11代码.我一直收到这个错误:

collin@Serenity:~/Projects/arraylib$ g++ ./t2.cpp
./t2.cpp:10:27: error: expected ‘,’ or ‘...’ before ‘&&’ token
./t2.cpp:10:38: error: invalid constructor; you probably meant ‘Blarg (const Blarg&)’
Run Code Online (Sandbox Code Playgroud)

我正在编写的程序与此完全不同,但我将其修改为看起来应该绝对可行的部分,但仍会触发错误:

#include <iostream>

using namespace std;

class Blarg {
    public:
        Blarg () {};
        Blarg (const Blarg& original) {}; /* Copy constructor */
        Blarg (Blarg&& original) {}; /* Move constructor */
};

int main(int argc, char *argv[])
{
    Blarg b;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

谁能告诉我我做错了什么?相反,如何解决它?

这是我的gcc版本:

gcc (Ubuntu/Linaro 4.6.2-14ubuntu2) 4.6.2
Run Code Online (Sandbox Code Playgroud)

c++ g++ move-constructor c++11

21
推荐指数
2
解决办法
3万
查看次数

为什么复制和移动构造函数一起调用?

请考虑以下代码:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
     A(int) { cout << "int" << endl; }
     A(A&&) { cout << "move" << endl; }
     A(const A&) { cout << "copy" << endl; }
};

int main()
{
    vector<A> v
    {
        A(10), A(20), A(30)
    };

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

输出是:

int
int
int
copy
copy
copy
Run Code Online (Sandbox Code Playgroud)

A(10),A(20)并且A(30)是临时对象,对不对?

那么为什么复制构造函数被调用?不应该调用移动构造函数吗?

路过move(A(10)),move(A(20)),move(A(30))相反,输出为:

int
move
int
move
int
move
copy …
Run Code Online (Sandbox Code Playgroud)

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

21
推荐指数
2
解决办法
1569
查看次数

使用std :: pair或std :: tuple的移动语义

假设你想利用移动语义,但你的一个可移动类需要成为一部分std::pair.目的是创建一个函数,该函数返回一个std::pair可被视为右值并转发的函数.

但我无法看到如何做到这一点,除非对其std::pair自身进行内部更改,以使其了解移动语义.

请考虑以下代码:

struct Foo
{
 Foo() { }

 Foo(Foo&& f) { }

 private:

 Foo(const Foo& f) { } // do not allow copying
};

int main() 
{
 Foo f;
 std::pair<Foo, int> res = std::make_pair(f, 10); // fails due to private copy constructor
}
Run Code Online (Sandbox Code Playgroud)

问题是std::make_pair,除了std::pair构造函数本身之外,还需要两个对象并尝试制作它们的内部副本.这导致它尝试并调用复制构造函数.但在我的例子中,我希望能够新对移动res,并确保不会制作副本.我认为除非std::pair自己在内部定义了以下构造函数,否则这是不可能的:

pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2))
Run Code Online (Sandbox Code Playgroud)

但它没有,至少在我使用的编译器上没有(gcc 4.3.2).这可能是因为我的编译器是简单地外的日期,而事实上新版本拥有这一举动感知构造.但是我对移动语义的理解目前有点不稳定,所以我不确定我是否只是在这里忽略了一些东西.那么,我是否正在努力实现,而不是实际重新实现std::pair?或者我的编译器是否已过时?

c++ move-constructor move-semantics c++11 std-pair

20
推荐指数
1
解决办法
1万
查看次数

使用成员std :: vector移动语义

很抱歉,如果之前已经询问过,但据我所知,在C++ 11中,std::vector有一个移动构造函数,因此在某些情况下复制成本几乎没有,比如按值返回一个.但是,如果我有这样的类,使用vector作为成员变量:

class MyClass {
public:
    MyClass() { }
    MyClass(const MyClass& rhs) { }

    // other interfaces

private:
    std::vector<int> myvec;

    // implementation
};
Run Code Online (Sandbox Code Playgroud)

并且有一个函数可以按值返回其中一个,例如

MyClass somefunc() {
    MyClass mc;
    // fill mc.myvec with thousands (maybe even millions) of ints
    return mc;
}
Run Code Online (Sandbox Code Playgroud)

即使本身对移动构造函数一无所知,是否mc.myvec会调用移动构造函数和std::vector利用MyClass移动构造函数?或者是否vector要调用复制构造函数,并且int必须逐个复制所有数千个(甚至数百个)的复制构造函数?

c++ vector move-constructor c++11

19
推荐指数
1
解决办法
3429
查看次数

为什么这段代码试图调用复制构造函数?

我花了大量的时间来摆弄Visual Studio中的complilation错误.我已经将代码提炼到下面的小编译示例中,并在IdeOne上尝试了它并得到了同样的错误,你可以在这里看到.

我想知道为什么以下代码尝试调用B(const B&)而不是B(B&&):

#include <iostream>

using namespace std;

class A {
public:
    A() : data(53) { }
    A(A&& dying) : data(dying.data) { dying.data = 0; }

    int data;

private:
    // not implemented, this is a noncopyable class
    A(const A&);
    A& operator=(const A&);
};

class B : public A { };

int main() {
    B binst;

    char* buf = new char[sizeof(B)];

    B* bptr = new (buf) B(std::move(binst));

    cout << bptr->data << endl;

    delete[] buf; …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor placement-new move-constructor c++11

18
推荐指数
2
解决办法
2306
查看次数

为什么移动构造函数需要其成员的默认构造函数?

我试图为没有复制构造函数的类实现移动构造函数.我收到一个错误,该类的成员的默认构造函数丢失.

这是一个简单的例子来说明这一点:

struct A {
public:
        A() = delete;
        A(A const&) = delete;
        A(A &&a) {}
};

struct B {
        A a;
        B() = delete;
        B(B const&) = delete;
        B(B &&b) {}
};
Run Code Online (Sandbox Code Playgroud)

试着编译这个,我得到:

move_without_default.cc: In constructor ‘B::B(B&&)’:
move_without_default.cc:15:11: error: use of deleted function ‘A::A()’
  B(B &&b) {}
           ^
move_without_default.cc:6:2: note: declared here
  A() = delete;
  ^
Run Code Online (Sandbox Code Playgroud)

为什么这是一个错误?有什么办法吗?

c++ default-constructor move-constructor

18
推荐指数
3
解决办法
1437
查看次数