whI have 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 see B C and D inherit from A, A being the base class. Class D must have a specific alignment (because SSE2 is used inside it), hence why I overloaded new/delete inside it, providing an aligned block of memory each time the object is dynamically allcated. Should also I mention since A B C and D differ, I would pretty much guess B C A and D do not have the same size at all.
So I would like to be able to do that:
E eobj(12, new D(2.001), true);
Because the parameter IsObjPtrOwner would be true, I programmed my class E so that, if the member m_IsObjPtrOwner is true, the pointer m_objptr is deleted inside the destructor of E.
This would be very convenient for me to be able to dynamically allocate one of the derived classes of A directly while constructing the object E, and not have to care about it later. The reason for this is that I will be making a lot of instances of class E throughout my program, each time with a different B/C/D instance. So I would like not to have to keep a copy of each pointer I create each time I construct an instance of E.
So I tried to make new/delete operators pure virtual, but it just won't work. The damn functions must be static, very bothering. So I tried to circumvent this as much as I could, but I ended up discovering I cannot use "this" inside static functions.
What can I do? How can I realize this dream? I have a dream...
EDIT: For some reasons people do not understand at all what I'm 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 taking as an argument in its constructor a pointer of class A, which is then stored in a member, say 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 see, each of em have different alignment requirements.
Now I have a 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 that:
E einst(2, new D(2.001));
i.e. I don't keep a copy of the D object allocated. The allocated D object would be freed while "einst" is destroyed. The problem is that this code will not work. When deleting m_bcdobj inside ~E(), the overloaded delete operator inside D will not be called.
Thanks!
operator delete is special in that despite being a static member, if the class has a virtual destructor it is dynamically dispatched. §12.5 [class.free]/p4:
If the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one selected at the point of definition of the dynamic type’s virtual destructor (12.4).
For example,
struct B {
virtual ~B() = default;
void operator delete(void* ptr) {
std::cout << "B's operator delete" << std::endl; ::operator delete(ptr);
}
};
struct D : B {
void operator delete(void* ptr) {
std::cout << "D's operator delete" << std::endl; ::operator delete(ptr);
}
};
int main() {
B* bp = new D;
delete bp; //1: uses D::operator delete(void*)
}
prints:
D's operator delete
Thus, give A a virtual destructor and you should see the correct operator delete called :).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With