C++之析构函数和构造函数调用时间---补充(2)《Effective C++》
来源:互联网 发布:汽车行业制图软件 编辑:程序博客网 时间:2024/06/05 00:58
今天看书忽然对这个地方有点模糊,尤其是析构函数在调用默认的析构函数和用户自己覆写的析构函数的时候有点意识模糊呢。写段代码总结下
- #include <iostream>
- using namespace std;
- class Box
- {
- private:
- double length;
- public:
- Box(double lv=1.0):length(lv)//构造函数都没有返回值
- {
- cout << ”constructor called” << endl;
- }
- ~Box()//重写的析构函数(重写是对继承类对基类的重新构造,这里表述不对)
- {
- cout << ”destructor called” << endl;
- }
- };//万恶的分号,我老是忘掉
#include <iostream>using namespace std;class Box{private: double length;public: Box(double lv=1.0):length(lv)//构造函数都没有返回值 { cout << "constructor called" << endl; } ~Box()//重写的析构函数(重写是对继承类对基类的重新构造,这里表述不对) { cout << "destructor called" << endl; }};//万恶的分号,我老是忘掉
1、首先直接声明(定义)看下
//很多朋友指出我这里用声明不合适,在11楼作了一定解释,具体不在这里赘述,这里改为“定义”,谢谢大家的指正,但我也保留我自己的意见,所以没有把“声明”去掉
- int main()
- {
- Box box(2.3);
- }
int main(){ Box box(2.3);}
这里看到一点Java与c++的不同点,c++在声明的时候就创建了对象,java声明只是创建一个引用,并不会分配内存。言归正传,说明声明以后就调用了构造函数,然后退出的时候调用析构函数。
2、声明指针
- int main()
- {
- Box *box;
- }
int main(){ Box *box;}
可以看到,声明指针并不会调用构造函数,也不会分配内存空间。
3、用new创建
- int main()
- {
- Box *box=new Box(2.3);
- }
int main(){ Box *box=new Box(2.3);}
仅仅是调用构造函数创建了对象,分配了内存空间。但是没有调用析构函数,因为box指定的对象的内存是由new来创建分配的,编译器不能够自动调用析构函数将其删除。所以需要调用delete才可以。
4、用new创建对象,并delete掉
- int main()
- {
- Box *box=new Box();
- delete box;
- }
int main(){ Box *box=new Box(); delete box;}
这次调用了析构函数。可以看出,此时的析构函数不是编译器自己调用的,是由我们的程序来主动调用的,所以以后需要注意。new了的需要手动释放内存空间
5、什么时候需要重写析构函数?
- class Message()
- {
- private:
- char *message;
- public:
- Message(const char* text=“default message”)
- {
- message = new char[strlen(text)+1];
- strcpy(message, text);
- }
- void showit()
- {
- cout << ”message: ” << message << endl;
- }
- ~Message()
- };
- Message::~Message()
- {
- cout << ”destructor called” << endl;
- delete [] message;
- }
class Message(){private: char *message;public: Message(const char* text="default message") { message = new char[strlen(text)+1]; strcpy(message, text); } void showit() { cout << "message: " << message << endl; } ~Message()};Message::~Message(){ cout << "destructor called" << endl; delete [] message;}
从例子可以看到,当你的构造函数中调用了new来创建对象的内存分配空间,则需要专门调用delete来释放内存,所以此时需要覆写析构函数,来专门的释放此内存空间
6、对象的形参传值问题:(话外题,仅作记录用)
先看代码及运行结果
- #include <iostream>
- using namespace std;
- class Box
- {
- private:
- double length;
- public:
- Box(double lv=1.0):length(lv)//构造函数都没有返回值
- {
- cout << ”constructor called” << endl;
- }
- ~Box()
- {
- cout << ”destructor called” << endl;
- }
- void showit()
- {
- cout << this->length << endl;
- }
- };
- void display(Box box)//关键注意这个地方。。。。。。。。。。。。。。。。。。。。。。。。。
- {
- box.showit();
- }
- int main()
- {
- Box box;
- display(box);
- }
#include <iostream>using namespace std;class Box{private: double length;public: Box(double lv=1.0):length(lv)//构造函数都没有返回值 { cout << "constructor called" << endl; } ~Box() { cout << "destructor called" << endl; } void showit() { cout << this->length << endl; }};void display(Box box)//关键注意这个地方。。。。。。。。。。。。。。。。。。。。。。。。。{ box.showit();}int main(){ Box box; display(box);}
运行结果
如果将上面的display代码改为
- void display(Box &box)//改为调用的是引用
- {
- box.showit();
- }
void display(Box &box)//改为调用的是引用{ box.showit();}运行结果
可以明显的看到不加引用的时候会出现两个析构函数的调用。为什么呢?
直接传参,是形参传递,所以会另外创建一个对象来复制main函数里的对象box,所以在display调用完成时刻要调用析构函数来释放这个函数创建的形参对象的内存空间。但是如果是传递的引用,就只有一个参数对象了,所以只调用一个。
如果是平时的基本类型,你应该了解,直接把main里的box的值复制给形参box就是了,但是到了对象这里就有点复杂,如果是里面就是单纯的像上面的例子一样double类型等,其自带有复制函数就可以将各个成员值复制到形参对象里,但是如果里面有引用,比如char *pp = new char[100],那么复制的只是地址,两个对象公用一个地址,有可能就会造成错误。所以以后需要注意这一点,调用对象需要用引用哦。。。。。(要不你自己另写一个复制函数。)
- C++之析构函数和构造函数调用时间---补充(2)《Effective C++》
- C++之构造函数和析构函数中不要调用virtual函数(9)---《Effective C++》
- 《Effective C++》不要在构造函数和析构函数中调用虚函数
- 【Effective c++】条款09:绝不再构造和析构过程中调用virtual函数
- Effective C++:条款09:绝不在构造和析构过程中调用virtual函数
- 读书笔记《Effective C++》条款09:绝不在构造和析构过程中调用virtual函数
- <Effective C++> Item 9:绝不在构造和析构过程中调用虚函数
- Effective c++(3th) Item9:绝不要在构造和析构期间调用虚拟函数
- C++之const对象只能调用const成员函数---补充(18)《More Effective C++》
- 【effective C++】不要在构造函数或析构函数内调用虚函数
- [C++]显示调用构造函数和析构函数
- 《Effective C++》学习笔记条款09 决不让构造和析构过程中调用virtual函数
- Effective C++——》条款9:绝不在构造和析构过程中调用virtual函数
- Effective C++ 笔记之六 绝不在构造和析构函数中调用virtual函数
- C#OOP之六 构造函数和析构函数
- 构造函数和析构函数【c++】
- [c++]构造函数和析构函数
- 【C#】构造函数和析构函数
- Reactor模式软文
- js动态改变地址栏url,不刷新页面
- java死锁的原因分析及解锁和预防措施
- mysql事务
- Visual Studio 实用插件
- C++之析构函数和构造函数调用时间---补充(2)《Effective C++》
- lnmp
- kaggle Code :手写识别 TensorFlow
- MATLAB R2011b 神经网络工具箱注意事项
- java中的运算符
- idea默认文件编码格式设置
- python list排序的两种方法及实例讲解
- 深度学习batchsize,iteration,epoch的关系
- 关于uEditor,上传图片到指定主机(图片服务器)