zoukankan      html  css  js  c++  java
  • c++构造/拷贝构造函数初始化变量*

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

    class Person {
       public:
        int id;
        string name;

       public:
        Person() {
            this->id = 200;
            cout << "None param constructor" << endl;
        }

        /* explicit */ Person(int id) {
            cout << "One param constructor" << endl;
            this->id = id;
        }

        Person(int id, string name) {
            this->id = id;
            this->name = name;
            cout << "Two params constructor" << endl;
        }

        // 如果参数不加const, 这种Person pp4 = Person(1, "qiumc");写法会报错,因为Person(1, "qiumc")产生一个临时右值,
        // 临时右值在通过copy构造函数赋值给左值(copy构造函数的参数)的时候,不能赋值给非const的左值。
        Person(const Person& p) {
            this->id = p.id;
            this->name = p.name;
            cout << "copy constructor" << endl;
        }

        Person(Person&& p) {
            this->id = p.id;
            this->name = p.name;
            cout << "move constructor" << endl;
        }

    };

    /**
     * @brief
     * 整形初始化的几种方式
     */
    void TestIntInit() {
        // case1
        int i1 = 100;

        // case2
        int i2(100);
        int i3{100};

        // case3
        int i4 = int(100);
        int i5 = int{100};

        // case4
        int i6 = {100};
    }

    /**
     * @brief
     * 有参构造函数的几种写法
     */
    void TestPersonParamInit() {
        // case1
        // 这里发生了隐式转换,如果在单个参数构造函数前,加上explicit,将禁止这种隐式转化
        // 会先将1000隐士转化为Person(1000)临时对象,再将该临时对象调用copy构造函数,完成
        // 向pp1的赋值
        Person pp1 = 1000;

        // case2
        // 直接调用了两个参数的构造函数
        Person pp2(1, "qiumc");
        Person pp3{1, "qiumc"};

        // case3
        // 产生了临时对象Person(1, "qiumc"),然后将该临时对象调用copy构造函数赋值给pp4
        // 临时对象Person(1, "qiumc")是一个右值,而移动构造函数的参数类型是一个右值类型,所以,如果有移动构造函数,
        // 这种形式将会调用移动构造函数,没有移动构造函数,将会调用copy构造函数
        Person pp4 = Person(1, "qiumc");
        // 同上
        Person pp5 = Person{1, "qimmc"};

        // case4
        // 这种方式直接调用了两个参数的构造函数,而没有调用拷贝构造函数
        // 如果有移动构造函数,也不会调用移动构造函数
        // 这种形式也是一种单参数类型的隐式转化,如果两个参数的构造函数被声明为explicit形式,则这种定义将会报错
        Person pp6 = {1, "qiumc"};

        cout << pp1.id << " " << pp2.id << " " << pp3.id << " " << pp4.id << " " << pp5.id << " " << pp6.id << endl;
    }

    /**
     * @brief
     * 无参构造函数的几种写法
     */
    void TestPersonInit() {
        // 不能写成Person p1();因为这里无法和函数声明相区分开
        // 同上case2
        Person p2;
        Person p3{};

        // 同上case3,下面这两种,可以使用移动构造函数来减少拷贝
        Person p4 = Person();
        Person p5 = Person{};

        // 同上case4
        Person p6 = {};

    }

    /**
     * @brief
     * 一个参数的构造函数的简写方式
     */
    void TestPersonSingleParamInit() {
        // 如果没有类型符合的单参构造函数,这四种写法都会报错
        // 下面这些都是发生了隐式转化
        // 构造函数被声明为explicit时候,会禁止所有当前自定义的隐式类型转换,所以如果explicit修饰构造函数后,下面变量的定义都会报错
        // explicit ,当有一个构造函数的定义和声明的时候,只能出现在构造函数声明处,不能出现在构造函数的定义处
        Person p1 = 100;           // id = 100
        Person p2 = (200);         // id = 200
        Person p3 = (1, 2, 3, 4);  // id = 4

        Person p4 = {1};  //这种形式也是一种单参数类型的隐式转化,但是这种转换并没有产生临时对象后再调用copy构造函数
        cout << p1.id << ":" << p2.id << ":" << p3.id << endl;
    }

    /**
     * @brief
     * 拷贝构造函数的几种写法
     */
    void TestPersonCopy() {
        // 调用构造函数
        Person pp(1, "qiumc");

        // 调用拷贝构造函数
        Person pp1(pp);
        // 调用拷贝构造函数
        Person pp2{pp};

        // 第二次调用:如果如果有移动构造函数先调用移动构造函数,否则调用copy构造函数
        // 调用拷贝构造函数后,调用拷贝/移动构造函数
        Person pp3 = Person(pp);
        // 调用拷贝构造函数后,调用拷贝/移动构造函数
        Person pp4 = Person{pp};

        // 发生了隐式类型转换,但仅仅调用拷贝构造函数
        Person pp5 = {pp};

    }

    /**
     * @brief
     * 注意整型数据初始化,和自定义类型初始化,基本上是可以类比的。
     */
    int main(int argc, char const* argv[]) { TestPersonCopy(); }
  • 相关阅读:
    ros论坛
    python--dict和set类型--4
    python--条件判断和循环--3
    python--list和tuple类型--2
    Unicode与UTF-8互转(C语言实现)
    spring mvc 返回JSON数据
    值得学习的C语言开源项目和库
    mudos源码分析
    Freemarker使用总结
    Maven详解
  • 原文地址:https://www.cnblogs.com/qiumingcheng/p/15519150.html
Copyright © 2011-2022 走看看