用构造函数创建对象后,程序负责跟踪该对象,直到对象过期为止。对象过期时,程序将自动调用一个特殊的成员函数,该函数的名称——析构函数。
析构函数完成清理工作,实际上还是很有用的。
例如,用new来分配一个构造函数,则析构函数将使用delete来释放这些内存。Stock的构造函数没有使用new,因此析构函数实际上没有需要它清除的工作。在此情况下,只需要让编译器生成一个什么都不做的隐式析构函数即可,Stock类第一版正是这样做的。
和构造函数一样,析构函数的名称也很特殊:在类名前加上~。因此,Stock类的析构函数为~Stock()。另外,和构造函数一样,析构函数也可以没有返回值和声明类型。与构造函数不同的是,析构函数没有参数,因此Stock析构函数的原型必须是:
~Stock();
由于Stock的析构函数不承担任何重要的工作,因此可以将它编写为不执行任何操作的函数:
- Stock::~Stock()
- {
- }
但是,有时候为了能看出析构函数何时被调用,可以这样写代码:
- Stock::~Stock()
- {
- cout << "ByeBye," << company <<"!"<
- }
什么时候调用析构函数由编译器决定,通常不能再代码中显式地调用析构函数。如果
- 创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用。
- 创建的是自动存储类对象,则其析构函数将在程序执行完代码块时自动被调用。
如果对象是通过new创建的,则它将驻留在栈内存或者自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用。最后,程序可以创建临时对象来完成特定的操作,在这种情况下,程序将在结束对该对象使用时自动调用其析构函数。
由于在类对象过期时析构函数将自动被调用,因此必须有一个析构函数。如果程序员没有提供析构函数,编译器将隐式地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数的定义。
改进Stock类
下面将对构造函数和析构函数加入到类和方法的定义中。
1.头文件stock20.h,将构造函数和析构函数的原型加入到原来的类声明中。使用#ifndef防止多重包含。
- #ifndef __STOCK20_H__
- #define __STOCK20_H__
- #include
- class Stock
- {
- private:
- std::string company;
- long shares;
- double share_val;
- double total_val;
- void set_tot(){total_val = shares * share_val;}
- public:
- Stock();
- Stock(const std::string &co,long n,double pr);
- ~Stock();
- void buy(long num,double price);
- void sell(long num,double price);
- void update(double price);
- void show();
- };
-
- #endif
2.实现文件stock20.cpp使用了using声明和限定名称来访问头文件中的各种声明,将构造函数和析构函数的方法定义添加到以前的方法中。并且每次被调用时,都显式一条信息。
- #include
- #include "stock20.h"
-
- Stock::Stock()
- {
- std::cout<<"Default constructor called\n";
- company = "no name";
- shares = 0;
- share_val = 0.0;
- total_val = 0.0;
- }
- Stock::Stock(const std::string &co,long n,double pr)
- {
- std::cout<<"Constructor using"<
"called\n"; - company = co;
- if(n<0)
- {
- std::cout<<"Constructor using "<
"called\n" - <
"shares set to 0.\n"; - shares = 0;
- }
- else
- shares = n;
- share_val = pr;
- set_tot();
- }
-
- Stock::~Stock()
- {
- std::cout<<"Bye,"<
"!"< - }
- void Stock::buy(long num,double price)
- {
- if(num<0)
- {
- std::cout<<"Numer of shares can't be negative,Transaction is aborted"
- <
- }
- else
- {
- shares += num;
- share_val = price;
- set_tot();
- }
- }
- void Stock::sell(long num,double price)
- {
- if(num<0)
- {
- std::cout<<"Numer of shares can't be negative,Transaction is aborted"
- <
- }
- else if(num >shares)
- {
- std::cout<<"You can't sell more than you have!Trancsaction is aborted"
- <
- }
- else
- {
- shares -= num;
- share_val=price;
- set_tot();
- }
- }
- void Stock::update(double price)
- {
- share_val = price;
- set_tot();
- }
- void Stock::show() const
- {
- std::cout<<"Company:"<
- std::cout<<"Shares:"<
- std::cout<<"Share price"<
- std::cout<<"Total worth:"<
- }
3.客户文件,使用Stock类,显示了构造函数和析构函数。
- #include
- #include "stock20.h"
-
- int main()
- {
- {
- using std::cout;
- cout<<"Using constructors to create new objects\n";
- Stock stcok1("NanoSmart",12,20.0);
- stock1.show();
- Stock stock2=stock("Boffo objects",2,2.0);
- stock2.show();
-
- cout<<"Assingning stock1 to stock2:\n";
- stock2=stock1;
- cout<<"Listing stock1 and stock2:\n";
- stock1.show();
- stock2.show();
-
- cout<<"Using a constructor to reset an object\n";
- stock1=Stock("Nifty Foods",10,50.0);
- cout<<"Revised stock1:\n";
- stock1.show();
- cout<<"Done\n";
- const Stock land = Stock("Klu proper",3,3.0);
- land.show();
- }
- return 0;
-
- }
值得注意的是,main()的开头和末尾多了一个大括号。
诸如stock1和stock2等自动变量将在程序退出其定义所属代码块时消失。
如果没有这些大括号,代码块将为整个main(),因此只有main()执行完毕后,才会调用析构函数。在窗口环境中,这意味着将在析构函数调用前关闭,导致无法看到信息。但是添加大括号后,析构函数调用将在到达返回语句前执行,从而显式相应信息。
-
相关阅读:
CatBoost算法模型实现贷款违约预测
【vue3】08. 跟着官网学习vue3-列表渲染
这几个小妙招让你学会如何压缩图片大小
Redis之主从复制(一主两从)&薪火相传&反客为主&哨兵模式
安装显卡驱动报错
超低延时 TCP/UDP IP核
rsync远程同步
从0到1学会Git(第三部分):Git的远程仓库链接与操作
Android 10.0 wifi的随机mac地址修改为固定不变
Config
-
原文地址:https://blog.csdn.net/m0_73671341/article/details/133394704