移动构造函数的预期用法未发生

Expected usage of move constructor not happening

本文关键字:用法 构造函数 移动      更新时间:2023-10-16

这是我的类和程序:

class A {
    public:
        int x;
        int* v;
        A() : x(5), v(new int[5]) {cout<<"default ctor. "; for (int i=0; i<x; i++) v[i]=rand()%10;}
        A(const A& a) : x(a.x), v(new int[x]) {cout<<"copy ctor. "; for (int i=0; i<x; i++) v[i]=a.v[i]; }
        A(A&& a) : x(a.x), v(a.v) {cout<<"move ctor. ";a.x=0;a.v=0;}
        A& f() {return *this;}
        A g() {return *this;}
};
int main() {
    srand(time(0));
    cout<<"A a --> ";A a;cout<<endl;
    cout<<"A b(A()) --> ";A b(A());cout<<endl;
    cout<<"A c(a.f()) --> ";A c(a.f());cout<<endl;
    cout<<"A d(a.g()) --> ";A d(a.g());cout<<endl;
    cout<<"A e(A().g()) --> ";A e(A().g());cout<<endl;
}

我希望对象bde使用move构造函数,但我得到的输出是:

一个-->默认ctor。

A b(A())-->

一个c(A.f())-->复制ctor。

一个d(A.g())-->复制ctor。

一个e(A().g())-->默认ctor。复制ctor。

如果在这三种情况下,r值都是构造函数的参数,为什么不使用move构造函数?

显然,我使用-std=c++11选项进行编译。

使用b,您已经达到了"最麻烦的解析"。b是一个函数声明,而不是对象。

取表达式

A b(A());

让我们做一些名称更改和语义保留转换:

int foo(int (*p)());

现在,我认为很清楚foo是一个函数(返回int并将指向int()函数的指针作为参数)。现在用A代替int,用b代替foo,记住函数被隐式转换为指向函数的指针。你会发现这是一样的。

为了解决这个问题,你可以使用大括号初始化(感谢@MikeSeymour指出了这一点):

A b{A()};

对于d,我认为您是拷贝省略的"受害者"。"copy ctor"输出可能来自于用*this初始化返回值;从返回值到CCD_ 16的移动被完全消除。

有了e,情况就和d一样了。