C++ 新建/删除运算符重载和基类

C++ 新建/删除运算符重载和基类,c++,oop,operator-overloading,new-operator,delete-operator,C++,Oop,Operator Overloading,New Operator,Delete Operator,我现在头痛得厉害 基本上我有: 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) class B : public A { B(double x) : m_x(x) { bla bla bla} void *operator

我现在头痛得厉害

基本上我有:

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)
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); }
}
如您所见,bc和D继承自A,A是基类。类D必须有一个特定的对齐方式(因为它内部使用SSE2),因此我在它内部重载了new/delete,每次动态分配对象时都提供一个对齐的内存块。我还应该提到的是,由于bc和D不同,我几乎猜bca和D根本没有相同的大小

因此,我希望能够做到这一点:

E eobj(12, new D(2.001), true);
E einst(2, new D(2.001));
因为参数IsObjPtrOwner将为true,所以我编程了我的类E,这样,如果成员m_IsObjPtrOwner为true,指针m_objptr将在E的析构函数中删除

对于我来说,在构造对象E时能够直接动态地分配A的一个派生类是非常方便的,并且以后不必关心它。这样做的原因是,我将在整个程序中创建大量E类实例,每次都使用不同的B/C/D实例。所以我不想每次构造E的实例时都要保留我创建的每个指针的副本

所以我试着让new/delete操作符完全虚拟化,但它就是不起作用。该死的函数必须是静态的,非常麻烦。所以我尽可能地避开这个问题,但最终发现我不能在静态函数中使用“this”

我能做什么?我怎样才能实现这个梦想?我有一个梦想


编辑:由于某些原因,人们根本不明白我想说什么

我有一个基类a和一组从a派生的类B/C/D。我有一个类E,它的构造函数中有一个类a的指针作为参数,然后它存储在一个成员中,比如m_bcdobj,所以我有这个:

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)
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); }
}
如您所见,每个em都有不同的对齐要求

现在我有一个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;
}
所以我希望能够做到这一点:

E eobj(12, new D(2.001), true);
E einst(2, new D(2.001));
i、 e.我没有保留分配的D对象的副本。在销毁“einst”时,将释放分配的D对象。问题是这段代码不起作用。在~E()内删除m_bcdobj时,将不会调用D内重载的delete运算符


谢谢

运算符delete
的特殊之处在于,尽管它是静态成员,但如果类具有虚拟析构函数,则会动态调度它。§12.5[免费等级]/p4:

如果使用delete表达式取消分配其 静态类型有一个虚拟析构函数,释放函数是 在动态类型的虚拟对象的定义点处选择的一个 析构函数(12.4)

比如说,

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*)
}

因此,给
A
一个虚拟析构函数,您应该会看到正确的
操作符delete
名为:)。

我不理解这个问题。调用构造函数时,您不想动态分配
A*objptr
?你不想跟踪它吗?这与重载的
new
/
delete
操作符有什么关系?正如前面所说,必须使用特定的对齐方式分配B/C/D,除非我在每个操作符中重载new/delete,否则不会发生这种情况。另外,是的,我想在构造E时直接动态分配B/C/D,然后不再关心它。基本上,E的实例会在E本身被破坏时负责删除它。
操作符delete
是动态调度的,尽管它是一个静态函数,如果你问的是这个问题的话。我应该添加吗。我面临的问题是,当我删除E的析构函数中的A*objptr时,“delete objptr;”行不会调用类B/C/D的重载“delete”操作符,因为它会返回到与基类A关联的操作符。@Yannick
A
有虚拟析构函数吗?