Thursday, May 10, 2018

Vector of Smart Pointers with Template


#include <iostream>
#include <vector>
#include <memory>
#include <sstream>
#include <string>
#include <typeinfo>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}
    //Base(std::string const & tag, std::string const & desc) : m_tag(tag), m_desc(desc) {}
    ~Base() = default;

    void print();
    virtual void Process(); 

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


void Base::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}



template <class CNAME>
Base* createClass(char const *const tag, char const * const desc)
{
    CNAME * pObj  = new CNAME(tag,desc);

    std::cout << "Inside " << __FUNCTION__  << "(): ";
    pObj->Process();
    return dynamic_cast<Base*>(pObj);
}


template <class CNAME>
std::unique_ptr<Base> createUniqueClass(char const *const tag, char const *const desc)
{
    std::unique_ptr<Base> obj(createClass<CNAME>(tag, desc));
    return obj;
}



class KelasA : public Base
{
public:
    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;

    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};

std::string const KelasA::DefaultKelasName = "A";




void KelasA::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;
    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};


std::string const KelasB::DefaultKelasName = "B";


void KelasB::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class Container
{
public:
 template <class CNAME>
 void Add(std::string tag = "")
 {
  std::ostringstream sout;
  sout << __FUNCTION__ << ":Entry=" << m_bin.size();
  #define ANAM(x) #x
  m_bin.push_back(createUniqueClass<CNAME>(tag.c_str(), const_cast<char const *>(sout.str().c_str())));
 }

 void Process();


private:
    std::vector<std::unique_ptr<Base>> m_bin;
};



void Container::Process()
{
 for(auto & v : m_bin)
    {
        v->Process();
        v->print();
    }
}


int main()
{
 Container c;

 for(auto i = 0; i<10; ++i)
 {
  c.Add<KelasA>("A");
  c.Add<KelasB>("B");
 }

 c.Process();
 
    return 0;
}

No comments:

Post a Comment