美文网首页c++学习笔记
c++类型转换构造函数

c++类型转换构造函数

作者: 檀香静雪 | 来源:发表于2020-07-12 18:13 被阅读0次

    类型转换构造函数

    概念

    • 定义类型转换构造函数的目的是实现类型的自动转化

    • 只有一个参数,而且不是复制构造函数的构造函数,一般就可以看作是转换构造函数。

    • 当需要时,编译系统会自动调用转换构造函数,建立一个无名的临时对象。

    实现

    class Complex {//复数类
    public:
        double real, imag;
        Complex(double r, double i) {
            real = r;
            imag = i;
        }
        Complex(int r) {//类型转化构造函数
            real = r;
            imag = 0;
            cout << "int 类型转换构造函数被调用" << endl;
        }
        Complex(const Complex& c) {
            cout << "调用复制构造函数!!" << endl;
        }
        
    };
    

    对于上面的类,假设有如下实现:

    int main() {
        Complex c1(2, 3);
        Complex c2 = 3;
        c1 = 9;//9被转换为一个临时complex对象
        return 0;
    }
    

    在初始化c2的时候,参数只有一个3,为int类型,所以类型转换构造函数被调用。

    在执行c1 = 9的时候,由于c1已经存在,赋值号两边的类型不匹配,此时将调用类型转换构造函数将9转换为一个临时的Complex对象,在实现赋值。

    所以以上的程序执行结果为:

    int 类型转换构造函数被调用
    int 类型转换构造函数被调用
    

    析构函数

    构造函数是在对象生成的时候起作用的,而析构函数(Destructor)正好与之相反,析构函数在对象消亡的时候起作用。

    概念

    • 名字与类名相同,在前面加上~,没有参数和返回值,一个类最多只能有一个析构函数。
    • 析构函数在对象消亡时自动被调用,析构函数在对象消亡后做善后工作,比如释放内存空间。
    • 如果没写析构函数,那么编译器将自动生成一个缺省的析构函数,缺省的析构函数什么也不做。
    • 如果定义了析构函数,则编译器不再生成析构函数。

    实现

    有如下的Demo类:

    class Demo {
    public:
        char* p;
        Demo() {
            p = new char[20];
        }
        ~Demo(){
            delete[]p;
            cout << "析构函数被调用" << endl;
        }
    };
    

    Demo类生成时,动态申请了char[20]大小的空间。在对象消亡时,将释放这一部分空间并向屏幕输出:析构函数被调用

    对于上面的类,有如下的实现:

    int main() {
        Demo demo;
        return 0;
    }
    

    运行可以得到以下结果:

    析构函数被调用
    

    析构函数和数组

    如上面的Demo类所示,假设我们如下所示生成一个对象数组:

    int main() {
        Demo array[3];
        cout << "main end!" << endl;
        return 0;
    }
    

    在对象数组array的声明周期结束的时候,三个数组对象会依次执行析构函数,输出如下内容:

    main end!
    析构函数被调用
    析构函数被调用
    析构函数被调用
    

    析构函数和delete运算符

    delete运算符会导致析构函数被调用,如下代码所示:

    class Demo {
    public:
        char* p;
        Demo() {
            p = new char[20];
        }
        ~Demo(){
            delete[]p;
            cout << "析构函数被调用" << endl;
        }
    };
    int main() {
        Demo* demo;
        demo = new Demo;
        delete demo;
        return 0;
    }
    

    当执行到delete demo;时,析构函数将会调用,产生如下输出:

    析构函数被调用
    

    delete一个指针数组时,该数组元素也会依次调用析构函数,如下所示:

    int main() {
        Demo* array;
        array = new Demo[3];
        delete[]array;
        return 0;
    }
    

    此时析构函数将会被调用3次,产生如下输出:

    析构函数被调用
    析构函数被调用
    析构函数被调用
    

    注意:

    new一个对象数组,那么使用delete释放时应该写[],否则只delete一个对象,析构函数只被调用一次。

    对象作为函数返回值返回后调用析构函数

    • 当对象作为函数参数时,会导致复制构造函数的调用,同时在参数对象消亡时会导致析构函数被调用。

    • 当对象作为函数放回值使用时,也会导致析构函数被调用

    class Demo {
    public:
        char* p;
        Demo() {
            p = new char[20];
        }
        ~Demo(){
            cout << "析构函数被调用" << endl;
        }
    };
    Demo fun(Demo demo) {
        return demo;
    }
    
    Demo obj;
    
    int main() {
        obj = fun(obj);
        return 0;
    }
    

    在这里,我们定义了一个全局变量Demo obj;,当执行fun(obj)时,参数为一个对象,此时会导致析构函数被调用一次;

    同时,fun()函数返回一个对象,当完成obj = fun(obj);的赋值后,析构函数也会被调用一次;

    最后,全局变量obj消亡时析构函数在此被调用,所以以上样例产生如下输出:

    析构函数被调用
    析构函数被调用
    析构函数被调用
    

    相关文章

      网友评论

        本文标题:c++类型转换构造函数

        本文链接:https://www.haomeiwen.com/subject/ydhncktx.html