移动构造函数的预期用法未发生
Expected usage of move constructor not happening
这是我的类和程序:
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;
}
我希望对象b
、d
和e
使用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
一样了。
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 构造函数的用法
- 使用指针复制构造函数用法
- CPP/C 中的常量用法和结构构造函数中的澄清
- 复制构造函数方法的用法
- 参数和成员变量在构造函数中的用法
- C 中的构造函数和破坏者的内联用法
- 为什么内存泄漏只发生在赋值运算符重载的情况下,而不是在复制构造函数中,以及复制和交换习惯用法如何解决它
- 使用检测习惯用法来确定类型是否具有具有特定签名的构造函数
- C++:复制和交换习惯用法,替代构造函数
- 带有智能指针的虚拟构造函数习惯用法
- 如何实现拷贝交换习惯用法的复制构造函数
- 对象构造函数"settings"习惯用法
- c++单例用法:编译器抱怨私有构造函数
- 移动构造函数的预期用法未发生
- const char*在构造函数中的用法