I want that if an object is deleted then all the pointers to it are set to nullptr, or something like that

Manda Rajo 141 Reputation points
2022-03-19T10:27:51.26+00:00

Edit: I realized that I can compare pointers with the operator==, and I explain it in a post at bottom.

#include "stdafx.h"
#include <conio.h>

typedef unsigned long long UniqueId; // The reason it's 64-bit is a memory block can be freed and reallocated multiple times, which means that there can be a lot of ids.
UniqueId newUniqueId() {
    static UniqueId id = 0;
    return id++;
}
// Edit: Wrong-lesson: Never compare pointers using of the operator== because a pointer can be not unique,
// for example a deleted object and re-created object can have the same pointer, but use unique id.
bool areSame(GuiObject *obj1, GuiObject *obj2) {
    if ((obj1 != nullptr) && (obj2 == nullptr)) { return false; }
    if ((obj1 == nullptr) && (obj2 != nullptr)) { return false; }
    if ((obj1 == nullptr) && (obj2 == nullptr)) { return true; }
    if (obj1->_id == obj2->_id) { return true; }
    return false;
}
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,636 questions
{count} votes

Accepted answer
  1. RLWA32 43,306 Reputation points
    2022-03-19T16:16:57.28+00:00

    There are other classes in the Standard C++ library for managing pointers besides std::unique_ptr. Check out std::shared_ptr and std::weak_ptr.

    1 person found this answer helpful.

6 additional answers

Sort by: Most helpful
  1. RLWA32 43,306 Reputation points
    2022-03-19T12:55:01.66+00:00

    Change the MyObject == operator method to take a reference

        bool operator==(const MyObject& obj) const {
            return _id == obj._id;
        }
    

    Then you can use dereferenced pointers in your comparison -

        bool cmp1 = (*a == *b); 
    
    1 person found this answer helpful.

  2. Manda Rajo 141 Reputation points
    2022-03-19T15:00:03.033+00:00

    Ok, I was replacing all the operator== on GuiObject * with areSame(), and I realize that I don't need to do that, it's ok to compare pointers with ==, let me explain.

    RLWA32-6355 > its your responsibility to set them to nullptr after calling delete

    void MyClass::func(GuiObject *obj1) {
        // this->internal_obj2 was copied to the class MyClass from outside and if it's deleted outside then it's not changed to nullptr.
        EMC_CHECKEXISTENCE(this->internal_obj2); // The solution must be like this, the internal_obj2 must be a "dynamic var" or "variant", which means that if it's deleted somewhere else then this code cannot even reached, so no need to use areSame.
        if (obj1 == this->internal_obj2) { // This is ok because suppose that obj2 or internal_obj2 was accidentally deleted outside, and this line cannot even reached.
            printf("They are same");
        }
    }
    

    The reason I use the prefix "internal_" is as a warning, so when I read it, which means that it can be deleted outside but cannot be automatically set to nullptr internally.

    So, my new question is: "Does anyone has a suggestion? Because I don't know what is that dynamic variable in C++ I was talking about".

    0 comments No comments

  3. Manda Rajo 141 Reputation points
    2022-03-20T07:17:30.567+00:00

    Myself > Ok, thank you so much, I'm studying std::shared_ptr and std::weak_ptr. I believe that it's the solution of my problem.

    Example: https://stackoverflow.com/questions/12030650/when-is-stdweak-ptr-useful

    The reason I re-post the answer, is the comment sections are almost hidden inside tiny buttons (Show), and what if in a very far future, no body knows, when I will come back to visit this thread, then will I see the answers?

    0 comments No comments

  4. Manda Rajo 141 Reputation points
    2022-03-19T11:56:02.343+00:00

    RLWA32-6355 > So what are you trying to accomplish?

    The worst crash with a program made with C++ is always about "Pointers & Destruction", "Memory Leak", and the worst is about Destruction because it causes crash, and sometimes, crash that impossible to detect.

    I want to build a user interface (GUI) with so many objects in hierarchy (parents, and children, and linked objects with each other by using of pointers instead of strings because pointers are fast). I will use strings when performance is not required. What I want is when I delete an object then it sends signals to all the other objects linked to that deleted object, so the other objects will do actions of deleting too.

    184803-tooltip.jpg

    The code of hovering a menu item looks like this, but this is still in development, it's not stable.

       void TooltipManager::hoverObject(GuiObject *object) {  
           EMC_DEBUG_DISPLAYFLAGS(g_debug_displayFlags_tooltipManager);  
           if (areSame(object, _.internal_hoveredObject)) { // <-- Good practice, I'm not using the operator== to compare pointers.  
               return;  
           }  
           _.internal_hoveredObject = object;  
           //--------------------------------------------------  
         
           if (_.tick_isStarted == false) {  
               this->startTick(debug_displayFlags);  
           }  
           if (_.tooltip_isBegan == true) {  
               this->updateTooltip(debug_displayFlags);  
           }  
       }  
    

    How I delete an object by showing warning if a parent object is deleted before deleting its child object:

       enum DoesExist {  
           DoesExist_No  = 0x87654321, //  
           DoesExist_Yes = 0x12345678, // The reason of not using a boolean is for safe reason because when a memory is deleted then it becomes a random number.  
       };  
         
       #define EMC_CHECKEXISTENCE(obj) { \  
           EMC_VERIFY(obj != nullptr && "Don't use a nullptr."); \  
           EMC_VERIFY(obj->_existence == DoesExist_Yes && "Don't delete the parent object before deleting its child object, or maybe the object is just deleted when trying to use its pointer."); \  
       } ((void)0) // There must be ";".  
         
       GuiObject::~GuiObject()  
       {  
           _existence = DoesExist_No;  
         
           // Delete the object from its parent  
           if (_x.parent != nullptr) { // A window object doesn't have a parent object.  
               EMC_CHECKEXISTENCE(_x.parent); // A line like this shouldn't be evaluated if the parent doesn't exist because it makes a pointer to a deleted memory.  
         
               std::vector<GuiObject *> &vec = _x.parent->_x.objects;  
               for (int i = 0; i < vec.size(); i++) {  
                   if (vec[i] == this) { // WARNING: I find in the entire project about "==" then I found this bad practice, both are GuiObject *, I should write areSame(vec[i], this).  
                       vec.erase(vec.begin() + i);  
                       break;  
                   }  
               }  
           }  
       }  
    

    And another:

       GuiObject *obj = p->getLastObject();  
       if (obj == this) { // WARNING: I should write: areSame(obj, this).  
           ...  
       }  
    

    And there are a lot of of using of the operator == every where, bad old practice, I must replace them all with areSame().

    0 comments No comments