Home > Software design >  how to create derive class from base class
how to create derive class from base class

Time:11-24

I have base class like this:

class Base{
public:
    virtual Base *createNew(){
        auto newItem = new Base();
        setNew(newItem);
        return newItem;
    };

    void setNew(Base *item){
        item->value = value;
    };

private:
    int value;
};

A number of derived classes are shown below, each of which has a createNew interface that returns a derived object.

class Derive1 : public Base{
    Derive1 *createNew(){
        auto newItem = new Derive1();
        setNew(newItem);
        return newItem;
    };

    void setNew(Derive1 *item){
        Base::setNew(item);
        item->value1 = value1;
    };

private:
    int value1;
};

class Derive2 : public Base{
    Derive2 *createNew(){
        auto newItem = new Derive2();
        setNew(newItem);
        return newItem;
    };

    void setNew(Derive2 *item){
        Base::setNew(item);
        item->value2 = value2;
    };

private:
    int value2;
};

class Derive3 : public Base{
    Derive3 *createNew(){
        auto newItem = new Derive3();
        setNew(newItem);
        return newItem;
    };

    void setNew(Derive3 *item){
        Base::setNew(item);
        item->value3 = value3;
    };

private:
    int value3;
};

int main(int argc, char *argv[])
{
    std::list<Base *> list;
    list.push_back(new Derive1);
    list.push_back(new Derive2);
    list.push_back(new Derive3);
    list.push_back(new Derive2);
    list.push_back(new Derive1);

    std::list<Base *> listNew;
    for(auto item : list)
    {
        listNew.push_back(item->createNew());
    }
    ...
    //ignore the memory leak.
}

Is there any easy way to not write every createNew in the derived class, because they are similar, the only difference is the type. Do templates help?

CodePudding user response:

Supposedly you want to use the Curiously Recurring Template Pattern (CRTP) for this. Here is an example where we introduce template class BaseT that inherits from Base. Note how each derived class inherits from BaseT passing itself as template parameter.

class Base {
public:
  virtual Base* createNew() = 0;
  virtual ~Base() {}
};

template <typename T>
class BaseT : public Base {
public:
  Base* createNew() override {
    return createDerived();
  }

  T* createDerived() {
    auto newItem = new T();
    setNew(newItem);
    return newItem;
  };

  void setNew(T* item){
    item->value = value;
    setNewDerived(item);
  };

  virtual void setNewDerived(T* item) {}
  virtual ~BaseT() {}
private:
  int value;
};

class Derive1 : public BaseT<Derive1> {
public:
  void setNewDerived(Derive1* item) override {
    item->value1 = value1;
  }
private:  
  int value1;
};

class Derive2 : public BaseT<Derive2> {
public:
    void setNewDerived(Derive2 *item) override {
        item->value2 = value2;
    }
private:
    int value2;
};

class Derive3 : public BaseT<Derive3> {
public:
  void setNewDerived(Derive3 *item) override {
    item->value3 = value3;
  };
private:
    int value3;
};

Is this what you are trying to do?

  •  Tags:  
  • c
  • Related