New / removed operational overload and base class

with a big headache at the moment.

Basically I have this:

Class A -> Class B
Class A -> Class C
Class A -> Class D

Class E with constructor with declaration E(int, A *objptr, bool IsObjPtrOwner = true)

      

As you can see BC and D inherit from A, and A is the base class. Class D needs to have a certain alignment (because SSE2 is used inside it), so I overloaded / removed it inside it, providing an aligned block of memory every time the object is dynamically allcated. It should also be mentioned that since ABC and D are different from each other, I would almost guess that BCA and D are not the same size.

So I would like to be able to do this:

E eobj(12, new D(2.001), true);

      

Since the IsObjPtrOwner parameter would be true, I programmed my class E so that if the m_IsObjPtrOwner element is true, the m_objptr pointer is deleted inside the destructor E.

It would be very convenient for me to dynamically allocate one of the derived classes A directly when constructing the object E, and don't need to worry about that later. The reason for this is that I will be making many instances of class E throughout my program, each time with a different instance of B / C / D. Therefore, I would not want to keep a copy of every pointer I create every time I create an instance of E.

So, I tried to make the new / remove statements pure virtual, but that just won't work. Damn functions should be static, very annoying. So I tried to work around this as best I could, but I found I couldn't use "this" inside static functions.

What can I do? How can I make this dream come true? I have a dream...


EDIT: For some reason people don't understand at all what I am trying to say.

I have a base class A and a set of derived classes B / C / D from A. I have a class E that takes a class A pointer as an argument in its constructor, which is then stored in a member, like m_bcdobj, so I have this:

class B : public A {
    B(double x) : m_x(x) { bla bla bla}
    void *operator new(size_t size)   { return Util_MemAlign(size, 4); }
    void  operator delete(void* ptr)  { Util_AlignFree(ptr); }
}
class C : public A {
    C(double x) : m_x(x) { bla bla bla}
    void *operator new(size_t size)   { return malloc(size); }
    void  operator delete(void* ptr)  { free(ptr); }
}
class D : public A {
    D(double x) : m_x(x) { bla bla bla}
    void *operator new(size_t size)   { return Util_MemAlign(size, 16); }
    void  operator delete(void* ptr)  { Util_AlignFree(ptr); }
}

      

As you can see, they each have different alignment requirements.

Now I have class E:

class E {
    public:
        E(int z, A *bcdobj, bool IsObjPtrOwner = true) : m_z(z), m_bcdobj(bcdobj), m_freebcd(IsObjPtrOwner) { bla bla bla }

        ~E() { if (m_freebcd) { delete m_bcdobj; } }

    private:
        A *m_bcdobj;
        int m_z;
        bool m_freebcd;
}

      

So, I want to be able to do this:

E einst(2, new D(2.001));

      

i.e. I am not saving a copy of the allocated object D. The allocated object D will be deallocated and "einst" will be destroyed. The problem is that this code won't work. When deleting m_bcdobj inside ~ E (), the overloaded delete operator inside D will not be called.

Thank!

+3


source to share


1 answer


operator delete

the peculiarity is that, although it is a static member, if a class has a virtual destructor, it is dispatched dynamically. ยง12.5 [class.free] / p4:

If a delete expression is used to release an object of a class, the static type has a virtual destructor, the release function is one virtual destructor selected at the point of definition of dynamic types (12.4).

For example,

struct B {
    virtual ~B() = default;
    void operator delete(void* ptr) { 
        std::cout << "B operator delete" << std::endl; ::operator delete(ptr); 
    }
};
struct D : B {
    void operator delete(void* ptr) { 
        std::cout << "D operator delete" << std::endl; ::operator delete(ptr); 
    }
};
int main() {
    B* bp = new D;
    delete bp; //1: uses D::operator delete(void*)
}

      



prints :

D operator delete

      

Thus, give a A

virtual destructor and you should see the correct operator delete

one called :).

+4


source







All Articles