c/c++语言开发共享C++ 统一管理对象的删除,使用指针的指针**,或是指针的引用*&

懒得动写字了,直接贴多一些代码吧。主要是使用 指针的指针 或是 指针的引用,这里使用的是后者 指针的引用,因为这样函数的外部调用和内部代码编写起来会友好一些。指针的引用 只要考虑使用起来会比较安全一些,毕竟 引用参数(实参) 是必须传入一个 左值,就是要有一个指针对象传入,不能留空。简单的测试// jave.linvoid my_alloc(int*& ptr_ref) { ptr_ref = new int(99);}void my_free(int*& ptr_re

懒得动写字了,直接贴多一些 代码 与 注释吧。

主要是使用 指针的指针 或是 指针的引用,这里使用的是后者 指针的引用,因为这样函数的外部调用内部代码编写起来会友好一些

指针的引用 只要考虑使用起来会比较安全一些,毕竟 引用参数(实参) 是必须传入一个 左值,就是要有一个指针对象传入,不能留空。

简单的测试

// jave.lin void my_alloc(int*& ptr_ref) {     ptr_ref = new int(99); } void my_free(int*& ptr_ref) {     if (ptr_ref != NULL) {         delete ptr_ref;     }     ptr_ref = NULL; }  int main() {      int* ptr = NULL;     my_alloc(ptr);     std::cout << "after my_alloc(ptr);n";     if (ptr != NULL) {         std::cout << "ptr is not NULL, *ptr : " << *ptr << "n";     } else {         std::cout << "ptr is NULLn";     }     std::cout << "after my_free(ptr);n";     my_free(ptr);     if (ptr != NULL) {         std::cout << "ptr is not NULL, *ptr : " << *ptr << "n";     } else {         std::cout << "ptr is NULLn";     }     return 0; }  /* 输出: after my_alloc(ptr); ptr is not NULL, *ptr : 99 after my_free(ptr); ptr is NULL */ 

利用这一特性,我们可以将 的或是 结构体析构函数 的访问级别 设置为protected 或是 private ,这样可以不对外使用。(不能 delete ptr;来调用析构 或是 XXX::~XXX(); 的方式来析构)

然后都只能统一一个函数来 Destroy(xxx),这样删除的业务逻辑的内聚性变高,维护性高一些。

注意下面我们又对 GCC 与 MSVC 下的编译器有做区别处理。

特别是某个Destroy 过后的对象之前,它在其他地方有引用是,值会在不同编译、运行平台下有所区别。

我将区别写在了注释,特别留意我的注释说明即可,这里就不想重复写说明了:

// jave.lin void my_alloc(int*& ptr_ref) {     ptr_ref = new int(99); } void my_free(int*& ptr_ref) { 	if (ptr_ref != NULL) { 		delete ptr_ref; 	} 	ptr_ref = NULL; }  class Holder { public: 	int* p_int_value = NULL; }; int main() { 	Holder h; 	int* ptr = NULL; 	my_alloc(ptr); 	h.p_int_value = ptr; 	my_free(ptr); // 这时虽然 ptr == NULL,但是 h.p_int_value != NULL,他在 MSVC 与 GCC,或是其他编译器的上的值是不同的,这里我处理了 MSVC 与 GCC 的情况,其他没考虑 	#if GCC 	// GCC下直接判断h.p_int_value == NULL || *h.p_int_value == 0 	if (h.p_int_value == NULL || *h.p_int_value == 0) { 		h.p_int_value = NULL; 		std::cout << "h.p_int_value destroy outside"; 	} 	#else 	// MSVC下就比较特殊,h.p_int_value 	// 既不是 NULL,*h.p_int_value 会调用异常 	// 因为是h.p_int_value 地址是一个保护的、不可访问的地址:0xdddddddd 	// 所以判断需要调整 	if (h.p_int_value == NULL || (uint32_t)h.p_int_value == 0xdddddddd || *h.p_int_value == 0) { 		h.p_int_value = NULL; 		std::cout << "h.p_int_value destroy outside"; 	} 	#endif 	return 0; } 

完整测试代码

// jave.lin - 测试 Object 对象的统一管理删除 #include<iostream> #include<typeinfo>  // Check GCC #if __GNUC__ #   if __x86_64__ || __ppc64__ #   define ENVIRONMENT64 #   else #   define ENVIRONMENT32 #   endif #else // Check windows #   if _WIN32 || _WIN64 #   if _WIN64 #   define ENVIRONMENT64 #   else #   define ENVIRONMENT32 #   endif #   endif #endif  #ifdef ENVIRONMENT32 using address_t = unsigned int; #else using address_t = unsigned long long; #endif  #define P(content) std::cout << typeid(this).name() << " " << content << " : " << getName() << "n" // // Object 声明 // class Object { public:     // 使用引用指针,外部使用比较方便友好     static void Destroy(Object*& obj);     Object(std::string name = NULL);     inline const bool isDestroy() const;     inline const bool isBDestroy() const;     const std::string getName() const; protected:     // 私有析构,只能从 Object::Destroy(Object*&) 销毁     virtual ~Object(); private:     char* _isDestroy = NULL;     bool _isBDestroy = false;     std::string _name; };  // // Inherit 声明 // class Inheritor : public Object { public:     Inheritor(std::string name = NULL); private:     ~Inheritor(); };  // // Holder 声明 // class Holder : public Object { public:     Holder(std::string name = NULL);     inline void setObj(Object* obj);     inline Object* getObj() const; private:     ~Holder();     Object* _obj = NULL; };  // // Object 实现 // void Object::Destroy(Object*& obj) {     // 拿到指针的引用,如果指针不为 NULL     if (obj != NULL) {         // 没有被执行过销毁         if (!(obj)->isDestroy()) {             // 执行销毁             delete obj;             // 在获取一次isDestroy(),看看输出信息             obj->isDestroy();         }         // 将指针的引用赋值为 NULL         obj = NULL;     } }  Object::Object(std::string name) : _name(name) {     P("ctor");     _isDestroy = new char(0xFF); }  Object::~Object() {     P("desctor");     if (_isDestroy != NULL) {         delete _isDestroy;         _isDestroy = NULL;     }     _isBDestroy = true; }  inline const bool Object::isDestroy() const { #if __GNUC__     std::cout << typeid(this).name();     std::cout << " _isDestroy == NULL : " << (_isDestroy == NULL);     std::cout << ", *_isDestroy == 0  : " << (_isDestroy == NULL ? 0 : (*_isDestroy == 0)) << "n";     return _isDestroy == NULL || *_isDestroy == 0; #else     std::cout << typeid(this).name();     std::cout << " _isDestroy == NULL : " << (bool)(_isDestroy == NULL);     std::cout << ", (address_t)_isDestroy == 0xdddddddd  : " << ((address_t)_isDestroy == 0xdddddddd);     std::cout << ", *_isDestroy == 0  : " << (_isDestroy == NULL || ((address_t)_isDestroy == 0xdddddddd) ? 0 : (*_isDestroy == 0)) << "n";     return _isDestroy == NULL || (address_t)_isDestroy == 0xdddddddd || *_isDestroy == 0; #endif }  inline const bool Object::isBDestroy() const {     return _isBDestroy; }  const std::string Object::getName() const {     return _name; }  // // Inheritor 实现 // Inheritor::Inheritor(std::string name) : Object(name) {     P("ctor"); } Inheritor::~Inheritor() {     P("desctor"); }  // // Holder 实现 // Holder::Holder(std::string name) : Object(name) {     P("ctor"); } Holder::~Holder() {     P("desctor"); } inline void Holder::setObj(Object* obj) {     _obj = obj; } inline Object* Holder::getObj() const {     return _obj; }  void Test_funs(Object* obj) {     std::string backup_name = obj->getName();     // delete obj; // 私有接口就无法访问了,强制用户只用 Object::Destroy(Object*&)     Object::Destroy(obj);  // 对外部来说友好的接口     std::cout << "After Object::Destroy(" << backup_name << "):n";     if (obj == NULL) {         std::cout << backup_name << " == NULLn";     }     else {         std::cout << backup_name << " != NULLn";     } }  int main() {      std::cout << "=== Testing obj ===n";     Object* obj = new Object("obj");     Test_funs(obj);      std::cout << "n=== Testing inheritor ===n";     Inheritor* inht = new Inheritor("inheritor");     Test_funs(inht);      std::cout << "n=== Testing Hold something ===n";     Object* something = new Object("something");     Holder* holder = new Holder("holder");     holder->setObj(something);     Test_funs(something);      if (holder->getObj() != NULL) {         std::cout << "Holder->getObject() != NULL ";         std::cout << ", is destroy : " << holder->getObj()->isDestroy();         std::cout << ", is bBDestroy : " << holder->getObj()->isBDestroy() << "n";     }     else {         std::cout << "Holder->getObject() == NULL ";     }     Test_funs(holder);      return 0; }  /* 输出:  [VS2019]  === Testing obj === class Object * ctor : obj class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Object * desctor : obj class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(obj): obj == NULL  === Testing inheritor === class Object * ctor : inheritor class Inheritor * ctor : inheritor class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Inheritor * desctor : inheritor class Object * desctor : inheritor class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(inheritor): inheritor == NULL  === Testing Hold something === class Object * ctor : something class Object * ctor : holder class Holder * ctor : holder class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Object * desctor : something class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(something): something == NULL Holder->getObject() != NULL class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 , is destroy : 1, is bBDestroy : 221 class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Holder * desctor : holder class Object * desctor : holder class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(holder): holder == NULL  [GCC]  === Testing obj === P6Object ctor : obj PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Object desctor : obj PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(obj): obj == NULL  === Testing inheritor === P6Object ctor : inheritor P9Inheritor ctor : inheritor PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P9Inheritor desctor : inheritor P6Object desctor : inheritor PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(inheritor): inheritor == NULL  === Testing Hold something === P6Object ctor : something P6Object ctor : holder P6Holder ctor : holder PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Object desctor : something PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(something): something == NULL Holder->getObject() != NULL , is destroy : PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 0, is bBDestroy : 1 PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Holder desctor : holder P6Object desctor : holder PK6Object _isDestroy == NULL : 1, *_isDestroy == 0  : 0 After Object::Destroy(holder): holder == NULL */ 

VS 下输出

=== Testing obj === class Object * ctor : obj class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Object * desctor : obj class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(obj): obj == NULL  === Testing inheritor === class Object * ctor : inheritor class Inheritor * ctor : inheritor class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Inheritor * desctor : inheritor class Object * desctor : inheritor class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(inheritor): inheritor == NULL  === Testing Hold something === class Object * ctor : something class Object * ctor : holder class Holder * ctor : holder class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Object * desctor : something class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(something): something == NULL Holder->getObject() != NULL class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 , is destroy : 1, is bBDestroy : 221 class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 0, *_isDestroy == 0  : 0 class Holder * desctor : holder class Object * desctor : holder class Object const * _isDestroy == NULL : 0, (address_t)_isDestroy == 0xdddddddd  : 1, *_isDestroy == 0  : 0 After Object::Destroy(holder): holder == NULL 

GCC 下输出

=== Testing obj === P6Object ctor : obj PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Object desctor : obj PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(obj): obj == NULL  === Testing inheritor === P6Object ctor : inheritor P9Inheritor ctor : inheritor PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P9Inheritor desctor : inheritor P6Object desctor : inheritor PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(inheritor): inheritor == NULL  === Testing Hold something === P6Object ctor : something P6Object ctor : holder P6Holder ctor : holder PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Object desctor : something PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 After Object::Destroy(something): something == NULL Holder->getObject() != NULL , is destroy : PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 0, is bBDestroy : 1 PK6Object _isDestroy == NULL : 0, *_isDestroy == 0  : 0 P6Holder desctor : holder P6Object desctor : holder PK6Object _isDestroy == NULL : 1, *_isDestroy == 0  : 0 After Object::Destroy(holder): holder == NULL 

c/c++开发分享C++ 统一管理对象的删除,使用指针的指针**,或是指针的引用*&地址:https://blog.csdn.net/linjf520/article/details/107293123

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/599365.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐