2

TL;DR; - I want to be able to create object of child class inside function of parent class without specifying exact child class.

class CParent is used to store some data in m_data that is "version" specific. Each class CChild* will operate with its own group of data by the same rules inside this group.

Right now I have to declare CParent *replicate(int ver) in each CChild* class but they are the same and I thought that I can define this function in parent class only.

class CParent
{
public:
    int m_ver;
    std::vector<int>    m_data;
    CParent(int ver)
    {
        m_ver = ver;
    };
    CParent *replicate(int ver) { return nullptr; };
    void print(int ver) {
        if (m_ver == ver) {
            // print m_data
        }
        else {
            CParent *pobj = replicate(ver);
            // transfer data from 
            pobj->print(ver);
            delete pobj;
        }
    }
};

class CChild1 : public CParent
{
public:
    void CChild1::operator=(const CChild1& src)
    {
        // code transfering data from src(ver) to this(m_ver);
    };
    CChild1(int ver) :CParent(ver)
    {
        // code specific to CChild1 - m_data contain version depenedent data
    };
    CParent *replicate(int ver)
    {
        return new CChild1(ver);
    }
};

class CChild2 : public CParent
{
public:
    void CChild2::operator=(const CChild2& src)
    {
        // code transfering data from src(ver) to this(m_ver);
    };
    CChild2(int ver) :CParent(ver)
    {
        // code specific to CChild2 - m_data contain version depenedent data
    };

    CParent *replicate(int ver)
    {
        return new CChild2(ver);
    }
};


int main()
{
    int ver = 15;
    std::vector<CParent*> vecObjets;
    vecObjets.push_back(new CChild1(ver));
    vecObjets.push_back(new CChild2(ver));

    for (auto it : vecObjets)
        it->print(1);

    for (auto it : vecObjets)
        it->print(7);

    for (auto it : vecObjets)
        it->print(15);
}

I thought I could do something like that:

CChild* CChild::replicate(int iversion) {
    return new<decltype(*this)>(iversion);
};

So basically I need function to create replica of child class called from parent class. Can it be done?

  • 1
    https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp – spectras Jul 27 '18 at 11:49

1 Answers1

4

You can use the Curiously Recurring Template Pattern(CRTP) here for an indirection. You can read about CRTP on wiki if you find it interesting.

class Parent
{
 public:
    virtual Parent *replicate() = 0; 
};

template <typename Child>
class CRTP : public Parent
{
public:
    Parent *replicate()
    {
        return new Child();
    }
};

class Child1 : public CRTP<Child1> {};
class Child2 : public CRTP<Child2> {};
class Child3 : public CRTP<Child3> {};

int main()
{
    Parent *i1 = new Child1;
    Parent *i2 = new Child2;
    Parent *i3 = new Child3;

    Parent *i4 = i1->replicate();

    return 0;
}
Petok Lorand
  • 955
  • 6
  • 15