zoukankan      html  css  js  c++  java
  • c++之对象的初始化和清理

    在生活中我们购买单电子产品通常都会有出厂设置,在某一天我们不用也会删除一些自己的数据信息以保证安全。

    c++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁清理数据的设置。

    1.构造函数和析构函数

    对象的初始化和清理也是两个非常重要的安全问题:

    • 一个对象或者变量没有初始状态,对其使用后结果未知。
    • 同样的使用完一个对象或者变量,没有及时清理,也会造成一定的安全问题。

    c++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。对象的初始化和清理工作是编译器强制我们做的事情,因此如果我们不提供构造函数和析构函数,编译器会提供编译器提供的构造函数和析构函数的空实现。

    什么是构造函数?

    主要作用于创建对象时为对象的成员属性进行赋值。

    什么是析构函数?

    主要作用于对象在销毁时执行一些清理工作。

    构造函数语法:类名(){}

    • 构造函数,没有返回值也不写void
    • 函数名与类名相同
    • 构造函数可以有参数,因此可以重载
    • 程序在创建对象时会自动调用构造函数,而且只会调用一次

    析构函数语法:~类名(){}

    • 析构函数,没有返回值也不写void
    • 函数名与类名相同,在名称前面jiahsang~
    • 构造函数不可以有参数,因此不能重载
    • 程序在对象销毁时会自动调用析构函数,而且只会调用一次
    #include<iostream>
    using namespace std;
    
    class Student {
        string name;
        int age;
        double score;
    public:
        //构造函数
        Student(){
            cout << "调用构造函数" << endl;
        }
        //析构函数
        ~Student() {
            cout << "调用析构函数" << endl;
        }
    };
    
    void test() {
        //在栈上的数据,test执行完毕之后就会被释放
        Student s;
    }
    
    int main() {
        test();
        system("pause");
        return 0;
    }

    2.构造函数的分类以及调用

    两种分类方式:有参构造、无参构造;普通构造、拷贝构造;

    三种调用方式:括号法、显示法、隐式替换法;

    #include<iostream>
    using namespace std;
    
    class Student {
        string name;
        int age;
        double score;
    public:
        //无参构造函数
        Student(){
            cout << "调用Student()构造函数" << endl;
        }
        //有参构造函数
        Student(string name,int age) {
            cout << "调用Student(string name,int age)构造函数" << endl;
        }
        //拷贝构造函数
        Student(const Student &stu) {
            name = stu.name;
            age = stu.age;
            score = stu.score;
            cout << "调用拷贝构造函数" << endl;
        }
        //析构函数
        ~Student() {
            cout << "调用Student()析构函数" << endl;
        }
    };
    
    void test() {
        //匿名对象,当前行运行完后就会调用析构函数
        //不要使用拷贝构造函数初始化匿名对象:Student(s2);
        Student();
        //隐式三种形式
        cout << "隐式调用" << endl;
        Student s1;
        Student s2{"tom",12};
        Student s3{ s2 };
        //显示三种形式
        cout << "显示调用" << endl;
        Student s4 = Student();
        Student s5 = Student("bo",22);
        Student s6 = Student(s5);
        //隐式转换法,相当于Student s7 = Student{ "mike",17 };
        Student s7 = { "mike",17 };
    
    }
    
    int main() {
        test();
        system("pause");
        return 0;
    }

    输出:

    3.拷贝构造函数的调用时机

    c++拷贝构造函数调用时有三种情况

    • 使用一个已经创建完毕的对象来初始化一个新对象;
    • 值传递的方式给函数参数传输;
    • 以值方式返回局部对象; 

    即这三种情况下都会调用拷贝构造函数。

    #include<iostream>
    using namespace std;
    
    class Person {
    public:
        int m_age;
    public:
        Person() {
            cout << "Person默认构造函数" << endl;
        }
        Person(int age) {
            m_age = age;
            cout << "Person(int age)构造函数" << endl;
        }
        Person(const Person& p) {
            m_age = p.m_age;
            cout << "拷贝构造函数" << endl;
        }
        ~Person() {
            cout << "Person析构函数" << endl;
        }
    };
    
    //使用一个已经创建完毕的对象来初始化一个新对象
    void test() {
        Person p1(22);
        Person p2(p1);
        cout << "p2的年龄是:" << p2.m_age << endl;
    }
    void doWork(Person p) {}
    //使用值传递的方式
    void test2() {
        Person p;
        doWork(p);
    }
    //值返回局部对象
    Person doWork2() {
        Person p1;
        return p1;
    }
    void test3() {
        Person p = doWork2();
    }
    
    int main() {
        test3();
        system("pause");
        return 0;
    }

    4.构造函数的调用规则

    默认情况下,c++编译器至少会给一个类添加三个函数

    • 默认无参构造函数
    • 默认析构函数;
    • 默认拷贝构造函数,对属性进行值拷贝;

    构造函数调用规则如下

    • 如果用户自定义构造函数,c++不再提供无参构造函数,但是会提供拷贝构造函数;
    • 如果用户自定义拷贝构造函数,c++不会再提供其它构造函数;
  • 相关阅读:
    HDU1720 A+B Coming
    HDU1390 ZOJ1383 Binary Numbers
    HDU1390 ZOJ1383 Binary Numbers
    HDU2504 又见GCD
    HDU2504 又见GCD
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1020 ZOJ2478 Encoding
    HDU1020 ZOJ2478 Encoding
    HDU2097 Sky数
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12093375.html
Copyright © 2011-2022 走看看