动态分配时添加C 11对象列表?
发布时间:2020-12-16 03:16:04 所属栏目:百科 来源:网络整理
导读:假设我有一个类X: struct X{ ...}; 我有一个全局向量V: vectorX* V; 当且仅当动态分配(作为一个完整的大多数派生对象而不是一个子对象)时,我想向X添加一个X的新实例: int main(){ X x; // not added to V new X; // added to V struct D : X {}; new D; /
假设我有一个类X:
struct X { ... }; 我有一个全局向量V: vector<X*> V; 当且仅当动态分配(作为一个完整的大多数派生对象而不是一个子对象)时,我想向X添加一个X的新实例: int main() { X x; // not added to V new X; // added to V struct D : X {}; new D; // not added to V } 有没有办法这样做?也许是通过重载/覆盖运算符新的吗? 解决方法
基于
aschepler的方法,但现在使用虚拟基类来重定向D的构造函数调用(不向向量添加实例).
主要思想是进行两步注册:首先,将无效的new(无论是X或派生类)的任何调用注册到unordered_set(X :: dyn_alloc_set).然后,当构建X时,根据最多派生类型进行选择,如果已经被动态分配,则将其添加到V,如果它不是派生类. 虚拟基类的构造函数必须从最传统的类型中调用,因此可以在构造过程中使用它来区分D和X. #include <unordered_set> #include <typeinfo> #include <vector> #include <iostream> #include <algorithm> struct X; std::vector<X*> V; struct virt_base_class { friend struct X; private: virt_base_class(X* p); // this can only and will only be called by X public: virt_base_class() // this will be called by any class derived from X {} }; struct X : protected virtual virt_base_class { private: friend class virt_base_class; static std::unordered_set<X*> dyn_alloc_set; static bool dynamically_allocated(X* p) { return dyn_alloc_set.count(p) > 0; } public: X() : virt_base_class(this) {} static void* operator new(std::size_t size) { void* p = ::operator new(size); if (size == sizeof(X)) dyn_alloc_set.insert( static_cast<X*>(p) ); return p; } static void operator delete(void* p,std::size_t size) { if (size == sizeof(X)) { dyn_alloc_set.erase( static_cast<X*>(p) ); V.erase( std::remove(V.begin(),V.end(),static_cast<X*>(p)),V.end() ); } ::operator delete(p); } }; virt_base_class::virt_base_class(X* p) { if( X::dynamically_allocated(p) ) V.push_back(p); } struct D : X {}; // D::D will implicitly call virt_base_class::virt_base_class() std::unordered_set<X*> X::dyn_alloc_set; int main() { X x; X* p = new X; D d; D* pd = new D; std::cout << V.size(); } 更新:使用thread_local存储来避免unordered_set: struct X : protected virtual virt_base_class { private: friend class virt_base_class; static thread_local X* last_dyn_allocated; static bool dynamically_allocated(X* p) { return p == last_dyn_allocated; } public: X() : virt_base_class(this) {} static void* operator new(std::size_t size) { void* p = ::operator new(size); if (size == sizeof(X)) { last_dyn_allocated = static_cast<X*>(p); } return p; } static void operator delete(void* p,std::size_t size) { if (size == sizeof(X)) { X* pp = static_cast<X*>(p); if(last_dyn_allocated == pp) last_dyn_allocated = nullptr; V.erase( std::remove(V.begin(),pp),V.end() ); } ::operator delete(p); } }; thread_local X* last_dyn_allocated = nullptr; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Ancient Berland Circus CodeForces - 1C
- ruby-on-rails – Mongoid中的两个1-N关系(Rails)
- 复习Oracle数据库知识(一)——基本概念和sql简单语句
- ruby-on-rails – 从ruby 1.9.3升级到2.2.2时的性能问题
- FreeSWITCH - mod_xml_rpc源码分析七server.c
- 如何使用Flex Sound类处理加载错误
- ruby-on-rails-3 – Rails 3.验证邮件唯一性和区分大小写失
- c – 如何加快程序执行速度
- 中国天气网 天气预报API 国家气象局 根据城市名称抓取城市I
- c – xcode 7如何禁止警告“覆盖成员函数但未标记为’覆盖’
推荐文章
站长推荐
热点阅读