Categories

See More
Popular Forum

MBA (4887) B.Tech (1769) Engineering (1486) Class 12 (1030) Study Abroad (1004) Computer Science and Engineering (988) Business Management Studies (865) BBA (846) Diploma (746) CAT (651) B.Com (648) B.Sc (643) JEE Mains (618) Mechanical Engineering (574) Exam (525) India (462) Career (452) All Time Q&A (439) Mass Communication (427) BCA (417) Science (384) Computers & IT (Non-Engg) (383) Medicine & Health Sciences (381) Hotel Management (373) Civil Engineering (353) MCA (349) Tuteehub Top Questions (348) Distance (340) Colleges in India (334)
See More

Confused about how operator delete overriding is working

General Tech Bugs & Fixes

Max. 2000 characters
Replies

usr_profile.png

User

( 6 months 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 <iostream>

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?

usr_profile.png

User

( 6 months 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.

what's your interest


forum_ban8_5d8c5fd7cf6f7.gif