c – 如何查找继承类的分配地址
发布时间:2020-12-16 07:06:26 所属栏目:百科 来源:网络整理
导读:我试图创建一些通用的创建/删除功能,这些功能在普通的新/删除功能不可用的嵌入式环境中使用,并且在分配内存时必须使用module_id. 完整的代码可在以下网址查看:https://codereview.stackexchange.com/questions/33858/implementing-create-and-destroy-funct
我试图创建一些通用的创建/删除功能,这些功能在普通的新/删除功能不可用的嵌入式环境中使用,并且在分配内存时必须使用module_id.
完整的代码可在以下网址查看: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 42 int 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 42 int 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 42 int main() { MyClass *myclass = new(MODULE_ID) MyClass; Bar *bar = myclass; delete bar; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |