• 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容器时。

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

  • 相关阅读:
    人名币转大写
    Http协议与TCP协议简单理解
    unity3d常用属性汇总
    ConcurrentHashMap的key value不能为null,map可以?
    一个线程池中的线程异常了,那么线程池会怎么处理这个线程?
    Dubbo负载均衡算法
    [LeetCode] 240. 搜索二维矩阵 II ☆☆☆(二分查找类似)
    [LeetCode] 74. 搜索二维矩阵 ☆☆☆(二分查找)
    Maven中的dependencyManagement 意义
    深入理解maven构建生命周期和各种plugin插件
  • 原文地址:https://www.cnblogs.com/schsb/p/8606047.html
Copyright © 2020-2023  润新知