multimap<Base> basket; Base base; Derived derive; basket.insert(base); //ok,add copy of base; basket.insert(derive); //ok,but derive sliced down to its base part.
也就是说在把派生类的对象赋值给基类的时候,会发生切片效益,派生类的非基类部分会被切掉,那么就失去了本身的意义。为了解决这个问题我们可以
使用基于基类的指针或者引用,但是设计到指针问题的话就涉及到资源不使用后的释放问题。这就引出了句柄类,它类似智能指针,可以在我们复制资源
的时候不用去担心内存泄露的问题。整个程序的设计如下所示:
//Base.h #pragma once class Base { public: Base(void); virtual ~Base(void); virtual Base* clone() const; virtual void fine() const; private: int mb; };
//Base.cpp #include "Base.h" #include <iostream> using namespace std; Base::Base(void):mb(12) { } Base::~Base(void) { } Base* Base::clone() const { return new Base(*this); } void Base::fine() const { cout<<"Base fine function"<<endl; }
//Derive.h #pragma once #include "base.h" class Derive : public Base { public: Derive(void); virtual ~Derive(void); virtual Derive* clone() const; virtual void fine() const; private: int md; };
//Derive.cpp #include "Derive.h" #include <iostream> using namespace std; Derive::Derive(void):Base(),md(13) { } Derive::~Derive(void) { } Derive* Derive::clone() const { return new Derive(*this); } void Derive::fine() const { cout<<"Derive fine function"<<endl; }
//Handles.h #pragma once #include "Base.h" #include <iostream> class Handles { public: Handles(void); Handles(const Base&); Handles(const Handles& h); ~Handles(void); const Base* operator->()const; const Base& operator*()const; Handles& operator=(const Handles&); private: Base* p; std::size_t* use; void dec_use() { if(--*use == 0) { delete p; delete use; std::cout<<"delete resource"<<std::endl; } } };
//Handle.cpp #include "Handles.h" Handles::Handles(void):p(NULL),use(new size_t(1)) { } Handles::Handles(const Handles& h):p(h.p),use(h.use) { ++*use; } Handles::Handles(const Base& item):p(item.clone()),use(new std::size_t(1)) { } const Base& Handles::operator*()const { if(p) return *p; else throw std::logic_error("unbounded Handles"); } const Base* Handles::operator->()const { if(p) return p; else throw std::logic_error("unbounded Handles"); } Handles& Handles::operator=(const Handles& h) { ++*h.use; dec_use(); p = h.p; use = h.use; return *this; } Handles::~Handles() { dec_use(); }
//main.cpp #include <iostream> #include "Handles.h" #include "Derive.h" #include <vector> using namespace std; void main() { vector<Handles> mb; Base b; Derive d; mb.push_back(Handles(b)); mb.push_back(Handles(d)); mb[0]->fine(); mb[1]->fine(); system("pause"); }