C++中的构造函数和析构函数

c++程序中的初始化和清理工作,分别由两个特殊成员函数来完成,他们就是构造函数和析构函数。


构造函数

c++是一种面向对象的编程语言,它要让程序员使用类对象就像使用标准类型一样。
比如要你写一个函数,它的功能就好像int、char一样,能初始化一个Clock类对象,并且能将值赋给它的数据成员。而构造函数就可以定义这么一个对象,还可以同时对它的数据成员赋初值。
构造函数的作用就是在对象被创建时利用特定值构造一个对象,将对象初始化为一个特定状态。此外,它还有两个特殊性质:
- 构造函数的函数名和类名相同,且没有返回值
- 构造函数通常被声明为公有函数

#include<iostream>  
using namespace std; 

class Clock{
    public:
        Clock(int newH, int newM, int newS);          //构造函数
        void setTime(int newH, int newM, int newS);
        void showTime();
    private:
        int hour, minute, second;
};

void Clock::setTime(int newH, int newM, int newS){
    hour=newH;
    minute=newM;
    second=newS;
}

void Clock::showTime(){
    cout<<hour<<":"<<minute<<":"<<second<<endl;
}

Clock::Clock(int newH, int newM, int newS){
    hour=newH;
    minute=newM;
    second=newS;
}

int main(){
    Clock c(0, 0, 0);          //调用构造函数建立对象c
    c.showTime();
    c.setTime(8, 30, 30);
    c.showTime();
    return 0;
}

运行结果如下:
这里写图片描述
代码中的Clock c(0, 0, 0)就等于如下:、

Clock c = Clock(0, 0, 0);

这是显式调用,但是我们更经常用Clock c(0, 0, 0)这样格式紧凑的隐式调用。

如果main()里面这样声明对象:

Clock c;

编译器就会报错,因为面向对象的时候,你得给出必要的实参来。
还有一点需要注意的是,类成员名称(hour,minute,second)不能和构造函数参数名称(newH,newM,newS)设为一样,因为我们要将newH赋值给hour,等等。
至于默认构造函数和拷贝构造函数等概念,我们会在下次讲到。

析构函数

我们做事情的时候都要做好扫尾工作,写程序的时候当然也要。用构造函数创造的对象,程序会一直跟踪,直到其过期,由析构函数来完成清理工作。比如说一个函数中定义了几个局部对象,那么当这函数运行结束返回调用者时,函数中的对象也随之消失,消失的时候需要函数来释放其所占用的内存单元,这个函数就是析构函数。
简单来说,析构函数与构造函数作用相反,用来完成对象被删除前的一些清理工作。而且析构函数在对象生存期即将结束时被自动调用,调用之后,对象也就消失了,内存也被释放。

析构函数在类名称前加~,和构造函数一样的是,析构函数没有返回值和声明类型,与构造不同的是,析构函数没有参数。接着我们依旧拿原来的代码开刀:

#include<iostream>  
using namespace std; 

class Clock{
    public:
        Clock(int newH, int newM, int newS);          //构造函数
        void setTime(int newH, int newM, int newS);
        void showTime();
        ~Clock() {cout<<"调用析构函数"<<endl;}          //析构函数
    private:
        int hour, minute, second;
};


void Clock::setTime(int newH, int newM, int newS){
    hour=newH;
    minute=newM;
    second=newS;
}

void Clock::showTime(){
    cout<<hour<<":"<<minute<<":"<<second<<endl;
}

Clock::Clock(int newH, int newM, int newS){
    hour=newH;
    minute=newM;
    second=newS;
}

int main(){
    Clock c(0, 0, 0);
    c.showTime();
    c.setTime(8, 30, 30);
    c.showTime();
    return 0;
}

运行结果如下:
这里写图片描述
通过程序,我们可以看到析构函数等到对象被使用结束才被调用到。

因为一般情况下析构函数不担当重要作用,我们可以将其编写为不执行任何操作的函数:

~Clock() {}

但是为了能方便看出析构函数何时被调用,我们这样写:

~Clock() {cout<<"调用析构函数"<<endl;} 

一般的小函数,我们是不用自己来写析构函数的,因为编译器会隐式地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数定义。
但是有一种情况是,如果你对象通过new来创建,它将驻留在栈内存或自由存储区中,这时就必须使用delete来释放内存,其析构函数也将自动被调用。

猜你喜欢

转载自blog.csdn.net/weixin_41656968/article/details/80444546