Created
September 28, 2014 08:39
-
-
Save aont/26f7c520c4d19b5979ab to your computer and use it in GitHub Desktop.
vector of pointer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cstdio> | |
| #include <cstdlib> | |
| #include <typeinfo> | |
| #include <vector> | |
| class deleter_base | |
| { | |
| public: | |
| virtual ~deleter_base() {}; | |
| virtual void operator()(void* p) const = 0; | |
| }; | |
| template<class T> | |
| class deleter_impl : public deleter_base | |
| { | |
| public: | |
| virtual ~deleter_impl() { } | |
| public: | |
| virtual void operator()(void* const p) const | |
| { | |
| delete static_cast<T*>(p); | |
| } | |
| }; | |
| template<typename T> | |
| class ptr_vec | |
| { | |
| private: | |
| std::vector<T*> objects; | |
| std::vector<deleter_base*> deleters; | |
| public: | |
| ptr_vec() { } | |
| public: | |
| ~ptr_vec() | |
| { | |
| const size_t length = objects.size(); | |
| for(size_t i=0; i<length; ++i) { | |
| delete_at(i); | |
| } | |
| } | |
| public: | |
| template<typename S> | |
| void push_back(S* const ptr) | |
| { | |
| objects.push_back((T*)ptr); | |
| deleters.push_back(new deleter_impl<S>()); | |
| } | |
| private: | |
| void delete_at(const size_t idx) | |
| { | |
| T* obj = objects[idx]; | |
| deleter_base& deleter = *deleters[idx]; | |
| deleter(obj); | |
| delete &deleter; | |
| } | |
| public: | |
| void erase_at(const size_t idx) | |
| { | |
| delete_at(idx); | |
| objects.erase(objects.begin()+idx); | |
| deleters.erase(deleters.begin()+idx); | |
| } | |
| public: | |
| void erase_at(const size_t idx_begin, const size_t idx_end) | |
| { | |
| for(size_t idx=idx_begin; idx<idx_end; ++idx) { | |
| delete_at(idx); | |
| } | |
| objects.erase | |
| (objects.begin() + idx_begin, | |
| objects.begin() + idx_end); | |
| deleters.erase | |
| (deleters.begin() + idx_begin, | |
| deleters.begin() + idx_end); | |
| } | |
| public: | |
| bool empty() const | |
| { | |
| return objects.empty(); | |
| } | |
| public: | |
| size_t size() const | |
| { | |
| return objects.size(); | |
| } | |
| public: | |
| T* operator[](const size_t idx) const { | |
| return objects[idx]; | |
| } | |
| }; | |
| class Base | |
| { | |
| public: | |
| void say() const { | |
| this->say_virtual(); | |
| } | |
| virtual void say_virtual() const { | |
| fprintf(stderr, "[%s]\ttype:%s\n", __func__, typeid(*this).name()); | |
| } | |
| virtual ~Base() { | |
| fprintf(stderr, "[%s]\ttype:%s\n", __func__, typeid(*this).name()); | |
| } | |
| }; | |
| template<int i> | |
| class Derived : public Base | |
| { | |
| public: | |
| virtual void say_virtual() const { | |
| fprintf(stderr, "[%s]\ttype:%s\n", __func__, typeid(*this).name()); | |
| } | |
| virtual ~Derived() { | |
| fprintf(stderr, "[%s]\ttype:%s\n", __func__, typeid(*this).name()); | |
| } | |
| }; | |
| int main() | |
| { | |
| ptr_vec<Base> pvec; | |
| pvec.push_back(new Base()); | |
| pvec.push_back(new Derived<0>()); | |
| pvec.push_back(new Derived<1>()); | |
| pvec.push_back(new Derived<2>()); | |
| pvec.push_back(new Derived<3>()); | |
| pvec.push_back(new Derived<4>()); | |
| pvec.push_back(new Derived<5>()); | |
| for(size_t i=0; i<pvec.size(); ++i) { | |
| pvec[i]->say(); | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment