完整的代码可在以下网址查看:https://codereview.stackexchange.com/questions/33858/implementing-create-and-destroy-functions-to-replace-new-and-delete-oper
当使用多个固有类时,我在代码中发现了一个问题:
#include <stdlib.h>#include <stdint.h>#include <iostream>#include <utility>#include <new>using namespace std;template<typename T_,typename ...Args>T_ *create(uint32_t module_ID,Args&&... args) { // use module_ID T_ *p = (T_ *)calloc(1,sizeof(T_)); std::cout << "calloc: " << sizeof(T_) << " -> " << (voID *)p << std::endl; if (p) new (p) T_(forward<Args>(args)...); return p;}template<typename T_>voID destroy(T_ *t) { if (!t) return; t->~T_(); std::cout << "free: " << (voID *)t << std::endl; free(t);}struct Foo { int i[128]; virtual ~Foo() { }};struct bar { int j[128]; virtual ~bar() { }};struct MyClass : public Foo,public bar { int k[128]; virtual ~MyClass() { }};#define MODulE_ID 42int main() { MyClass *myclass = create<MyClass>(MODulE_ID); bar *bar = myclass; // Error bar != myclass destroy(bar);}
问题:如何修复/解决方法?该解决方案必须适用于使用gcc的linux,并且最好也适用于带有clang的linux
更新:基于user396672的评论
我相信下面的代码解决了我的问题,但有些细节可能仍然是错误的.另外,我想避免使用模板参数来解析module_ID
#include <stdlib.h>#include <stdint.h>#include <iostream>#include <utility>#include <new>using namespace std;template<unsigned ID,typename T>struct MyObjectWrapper : public T { template<typename ...Args> MyObjectWrapper(Args&&... args) : T(forward<Args>(args)...) { } voID* operator new(std::size_t count) { voID *p = calloc(1,sizeof(MyObjectWrapper<ID,T>)); std::cout << "calloc: " << ID << " " << sizeof(MyObjectWrapper<ID,T>) << " -> " << (voID *)p << std::endl; return p; } voID operator delete(voID *p) { std::cout << "free: " << p << std::endl; free(p); }};template<unsigned ID,typename T_,typename ...Args>T_ *create(Args&&... args) { return static_cast<T_ *>(new MyObjectWrapper<ID,T_>( forward<Args>(args)...));}template<typename T_>voID destroy(T_ *t) { delete /*static_cast<MyObjectWrapper<0,T_> *>*/(t);}struct Foo { int i[128]; virtual ~Foo() { }};struct bar { int j[128]; virtual ~bar() { }};struct MyClass : public Foo,public bar { int k[128]; ~MyClass() { }};#define MODulE_ID 42int main() { MyClass *myclass = create<MODulE_ID,MyClass>(); bar *bar = myclass; // Error bar != myclass destroy(bar);}
问题1:这是否正确
问题2:这可以做得更优雅吗?
问题3:我可以避免将module_ID作为模板参数传递,我可能会使用full来允许变量作为module_ID
问题4:MyObjectWrapper对象是否需要虚拟构造函数?我认为不需要它
解决方法 我建议使用附加参数(模块ID)创建一个包含operator new的基类.然后只需从中继承您的类#include <stdlib.h>#include <stdint.h>#include <iostream>#include <utility>#include <new>using namespace std;struct SpeciallyAllocated{ // operator new with additional parameter: voID* operator new(size_t sz,uint32_t mod_ID) { cout<<" module_ID alloacted:"<<mod_ID; return calloc(1,sz); } // matching delete (actually is not invoked w/o exceptions): voID operator delete(voID* p,uint32_t mod_ID){} // this one will be usually invoked: voID operator delete(voID* p){cout<<" object deleted"; free(p);} private: // prohibit (for safety reasons) other forms of new-delete operators: voID* operator new(size_t sz); voID* operator new[](size_t sz); voID operator delete[](voID* p);};struct Foo: public SpeciallyAllocated{ int i[128]; virtual ~Foo() { cout<< " Foo destructed"; }};struct bar: public SpeciallyAllocated { int j[128]; virtual ~bar() {{ cout<< " bar destructed"; } }};struct MyClass : public Foo,public bar { int k[128]; virtual ~MyClass() { cout<< " MyClass destructed"; }};#define MODulE_ID 42int main() { MyClass *myclass = new(MODulE_ID) MyClass; bar *bar = myclass; delete bar;}总结
以上是内存溢出为你收集整理的c – 如何查找继承类的分配地址全部内容,希望文章能够帮你解决c – 如何查找继承类的分配地址所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)