return时发生了啥

c++小白,谈谈看法,大神绕道

说起来,之前c++primer就有提及,return时会发生拷贝初始化。今天上课看书的时候突然想到,如果代码像下面这样:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 typedef struct xixi x;
 6 struct xixi {
 7     int xi;
 8     xixi(int i) { cout << "默认" << endl; }
 9     xixi(const x& n) { cout << "拷贝构造" << endl; }
10     xixi& operator=(const x& n) { 
11         cout << "赋值" << endl;
12         return *this; 
13     }
14     xixi& operator=(x&& n) {
15         xi = std::move(n.xi);
16         cout << "移动赋值" << endl;
17         return *this;
18     }
19     xixi(x&& n) :xi(std::move(n.xi)){ cout << "移动构造" << endl; }
20 };
21 
22 x f() {
23     x tmp(0);
24     return tmp;
25 }
26 
27 int main(void) {
28     x t(1);
29     t = f();
30     return 0;
31 }

各位看官先看main函数里,我纠结的是,如果没有把调用结果赋值给t,还会发生拷贝初始化吗,答案是会。没有赋值语句时,代码运行结果:

 在f()前加入"t="时,如下:

 也就是说,有没有赋值语句并不会影响return语句执行拷贝初始化,由于return一个临时对象,且提供了移动构造函数,拷贝初始化选择了移动构造,当没有提供构造函数时,退而求其次,选择拷贝构造函数。把调用结果赋值给t时,同理,有移动赋值就移动赋值,否则拷贝赋值,从而减少开销。

然后我还想说说--

 1 typedef struct node node;
 2 struct node {
 3     node(const node&) { cout << "拷贝" << endl; }
 4     //node(node&&) { cout << "移动" << endl; }
 5     node() { cout << "默认" << endl; }
 6     int xi;
 7 };
 8 
 9 int main(void) {
10     //binaryTree<int> xi;
11     int a[10] = { 6,5,2,5,7,8 };
12     vector<node> hhh;
13     for (int i = 0;i < 6;i++) {
14         node tmp;
15         hhh.push_back(tmp);
16     }
17     //for (int i = 0;i < 6;i++)xi.insert(&hhh[i]);
18     //xi.inorder();
19     return 0;
20 }

run一把是这样

???

一开始黑人问号,后来想到vector管理内存是不够就继续申请,所以在我的电脑上vs15在前几个push_back都是一次申请一个node大小的内存,直到倒数第二个才申请了大于或等压两个node的内存,当为node实现移动构造函数时,

会用移动构造函数去代替vector从旧内存到新内存的“搬运”工作,如果实现自己的类时尽量实现移动构造函数,从而减少拷贝的开销,特别是用到stl容器时。

这是今天的一点收获,说起来,其实很多小知识点都在书里看过,但碰到问题时还是没早点能想到原来是这样,实践啊实践出真知。继续前进吧(晚安嘻嘻

原文地址:https://www.cnblogs.com/schsb/p/8606047.html