目前我非常头疼。
基本上我有这个:
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)
如您所见,B C和D继承自A,A是基类。 D类必须具有特定的对齐方式(因为SSE2在其中使用),因此我在其中重载了new / delete,每次动态地对象提供对齐的内存块。我也应该提一下,因为A B C和D不同,我几乎猜测B C A和D根本没有相同的大小。
所以我希望能够做到这一点:
E eobj(12, new D(2.001), true);
因为参数IsObjPtrOwner是真的,所以我编写了我的类E,这样,如果成员m_IsObjPtrOwner为真,则在E的析构函数中删除指针m_objptr。
这对我来说非常方便,能够在构造对象E时直接动态分配A的派生类之一,而不必在以后关心它。这样做的原因是我将在整个程序中制作很多E类实例,每次使用不同的B / C / D实例。因此,我希望不必每次构建E实例时都保留每个指针的副本。
所以我尝试将new / delete运算符设为纯虚拟,但它只是不起作用。该死的功能必须是静态的,非常麻烦。所以我试图尽可能地绕过这个,但我最终发现我不能使用"这个"内部静态函数。
我该怎么办?我怎么才能实现这个梦想?我有一个梦想......
我有一个基类A和一组来自A的派生类B / C / D.我有一个E类,在它的构造函数中作为一个参数,一个A类的指针,然后存储在一个成员中,比如说m_bcdobj,所以我有这个:
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); }
}
如您所见,每个人都有不同的对齐要求。
现在我有一个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 einst(2, new D(2.001));
即。我没有保留分配的D对象的副本。分配的D对象将被释放,而#34; einst"被毁了。问题是这段代码不起作用。在~E()中删除m_bcdobj时,不会调用D中的重载删除操作符。
谢谢!
答案 0 :(得分:4)
operator delete
的特殊之处在于,尽管它是一个静态成员,但如果该类具有虚拟析构函数,则会动态调度它。 §12.5[class.free] / p4:
如果delete-expression用于释放其对象的类对象 static类型有一个虚拟析构函数,deallocation函数是 在动态类型的虚拟定义点选择一个 析构函数(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*)
}
D's operator delete
因此,给A
一个虚拟析构函数,你应该看到正确的operator delete
调用:)。