Confused about how operator delete overriding is working

General Tech Bugs & Fixes 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

So i'm trying to create a base class that has a default deallocation function for that type of base classes. Depending on how I delete a derived object I'm seeing different behaviour, maybe anyone can shed some light on why I'm not seeing my override working in the below commented cases where the custom deallocation is not invoked:

#include 

struct B {
    void operator delete(void* ptr) { 
        std::cout << "B's operator delete" << std::endl;
        ::operator delete(ptr); 
    }
};

struct D : B {
};

template<typename T>
class E {
public:
    E(T* inst) {
        //delete inst;            // invokes the operator delete override   
        T::operator delete(inst); // invokes the operator delete override
        //operator delete(inst);  // does not invoke the operator delete override
    }
};

int main() {
    D* dp = new D();
    E<D>* ep = new E<D>(dp);
    delete ep;
}

I'm guessing that the last attempt (invoking operator delete) without T:: uses the global deallocation function instead of my override, but why is that when delete inst is working just fine without having to specify T::?

I was expecting all three statements to actually invoke the delete operator for the object if it has been overriden. Can this be controlled through anything or is this correctly following the C++ ABI?

profilepic.png
manpreet 2 years ago

 

Not totally sure about this, but I think this is a scenario Stephen Dewhurst calls the "Operator Function Lookup Anomaly" in C++ Gotchas #23. He calls the explicit form to call an operator overload the "function call syntax" and shows an example in which infix syntax and function call syntax differ with respect to name lookup.

class X {
    public:
      X &operator %( const X & ) const;
      // ...
};

X &operator %( const X &, int );

void X::f() {
    X &anX = *this;
    anX % 12; // OK, non-member
    operator %( anX, 12 ); // error!
}

The use of the function call syntax follows the standard lookup sequence in searching for the function name. In the case of the member function X::f, the compiler will first look in the class X for a function named operator %. Once it finds the name, it won’t continue looking in outer scopes for additional functions named operator %.

Let's apply this to the operator delete scenario.

template<typename T>
class E {
  public:
    E(T* inst) {
        // delete inst; // Ok, infix call syntax
        // T::operator delete(inst); // Ok, qualified lookup enforced
        operator delete(inst); // The "anomaly"! This finds the operator delete for E
    }
};

Here, the name lookup stops at the operator delete that E provides, which is the default, global implementation. You can verify this by adding an operator delete member function to E.


0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.