在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
不用看了,2年前,自己功夫不够,没有想清楚,也觉得奇怪呢,忘记了 拷贝构造函数 这一说,结果导致本文 没有意义了。 其实我根本没有使用过这个想法的,后来的工作依然是 一个 new 一个delete。 原来以为 C++ 会自动进行类型转换,我错了。
再次声明,以下是错误的,现在经过修正了。红色为修正后。 ---------------------- 直接上代码。其实这是对类 和 指针 理解的一个案例。 #include<stdio.h> #include<iostream> using std::endl; using std::cout; /***************** 事实证明: 类的一般实例对象 只在所在函数有效,函数结束,这个类实例自动释放资源。 ***************/ #define DEBUG_FUNCTION_LINE() printf("#当前所在函数[%p] %s() 位于%d行\n",this,__FUNCTION__,__LINE__) class CServer1{ public: int isExit; public: CServer1(){ this->isExit=0; DEBUG_FUNCTION_LINE(); }; CServer1(const CServer1©){ ~CServer1(){ this->isExit=1; DEBUG_FUNCTION_LINE(); }; }; ////下面这个 函数 是否有缺陷??? CServer1 getPtrFunc (){ CServer1 *s=new CServer1(); s->isExit=15; return *s;//如果不用指针,局部变量会有错误的。Error 返回局部变量地址 是错误的。 结果: #当前所在函数 CServer1::CServer1() 位于18行
#当前所在函数 CServer1::CServer1() 位于18行
#当前所在函数 CServer1::~CServer1() 位于22行
foo->isExist=15
#当前所在函数 CServer1::~CServer1() 位于22行
@@@ Func2 完毕。
#当前所在函数 CServer1::CServer1() 位于18行
#当前所在函数 CServer1::~CServer1() 位于22行
@@@ Func3 完毕。
#当前所在函数[0x7fff5a39ec08] CServer1() 位于17行 #当前所在函数[0x7fbb60c03a00] CServer1() 位于17行 #当前所在函数[0x7fff5a39ec00] CServer1() 位于20行 #当前所在函数[0x7fff5a39ec00] ~CServer1() 位于29行 foo->isExist=15 #当前所在函数[0x7fff5a39ec08] ~CServer1() 位于29行 @@@ Func2 完毕。
#当前所在函数[0x7fbb60c03a10] CServer1() 位于17行 #当前所在函数[0x7fff5a39ec18] CServer1() 位于20行 #当前所在函数[0x7fff5a39ec18] ~CServer1() 位于29行 @@@ Func3 完毕。
构造函数 和 析构函数 是一一对应的。所以看到上面 没有少任何一个函数 ,说明 没有内存泄漏。 我用了一个 new ,但是没有delete。没有内存泄漏。 new的类,利用 函数返回值(以前我一直认为返回值 如果是类,必须得用指针呢,其实不用),直接返回类的实例对象,而不是指针,这样,new出来的就不需要delete,也会自然调用 析构函数了。
哈哈,,我好像 是 一个 小学生 突然发现 吸铁石 S N 互相吸引 ,SS NN互相排斥 一样。。。[果然跟小学生似的]
突然又想 反着来,返回一个指针 类型的,必须 delete 才能避免内存泄漏。但是 发现 使用函数返回值 我错了一次。。。 #include<stdio.h> #include<windows.h> #include<iostream> using std::endl; using std::cout; /***************** 事实证明: 类的一般实例对象 只在所在函数有效,函数结束,这个类实例自动释放资源。 ***************/ #define DEBUG_FUNCTION_LINE() printf("#当前所在函数[%p] %s() 位于%d行\n",this,__FUNCTION__,__LINE__) class CServer1{ public: int isExit; public: CServer1(){ this->isExit=0; DEBUG_FUNCTION_LINE(); };
#当前所在函数[0x7fff57113b48] CServer1() 位于18行 开始 调用getPtrFunc返回值 #当前所在函数[0x7f90e0403a00] CServer1() 位于18行 #当前所在函数[0x7fff57113b38] ~CServer1() 位于22行 结束 调用getPtrFunc返回值 foo->isExist=15 [=15 是正常的] #当前所在函数[0x7fff57113b48] ~CServer1() 位于22行 @@@ Func1 完毕。
开始 调用getPtrFunc返回值 #当前所在函数[0x7f90e0403a10] CServer1() 位于18行 #当前所在函数[0x7fff57113b58] ~CServer1() 位于22行 结束 调用getPtrFunc返回值 @@@ Func2 完毕。
#当前所在函数[0x7f90e0403a20] CServer1() 位于18行 开始 调用Func31。 #当前所在函数[0x7f90e0403a30] CServer1() 位于18行 #当前所在函数[0x7f90e0403a40] CServer1() 位于18行 #当前所在函数[0x7fff57113ab8] ~CServer1() 位于22行 In Func31: foo->isExist=15 [=15 是正常的] #当前所在函数[0x7fff57113b38] ~CServer1() 位于22行 结束 调用Func31。 In Func3: foo->isExist=15 [=15 是正常的] @@@ Func3 完毕。
#当前所在函数[0x7f90e0403a20] ~CServer1() 位于22行 最后一个函数完成了,delete下 也就没有内存泄漏了!!
*/
总结: 1.在getPtrFunc 函数中,虽然只有new,由于返回值 是 类实例 类型的,将指针 *p 返回,会在函数完成后自动销毁(即调用了和new对应delete 对应的 析构函数)。 2. 返回值类型为类实例的函数 的时候,不能对函数 使用 & 。正如 func3 的第一个版本,其实已经访问了释放过内存的区域了。(isExist=-1了)是不安全的。 3.上面说明,函数返回值 其实在取值的时候 是赋值,而不是 传递 地址。将 内存 拷贝,复制,有点 memcpy 的感觉。char[] 数组 如果可以这样赋值 多方便。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论