C++ CRTP constructor of derived class

Marco Agnese

I have some questions about the CRTP. Let's say I have the following code

#include <iostream>

// interface

template<class Imp>
class Interface{
  public:
    inline void print(void){
      std::cout<<"value: ";
      return asImp().print();
    }
  private:
    typedef Imp Implementation;
    inline Implementation& asImp(void){return static_cast<Implementation&>(*this);}
};

// add
class Add:public Interface<Add>{
  public:
    inline void print(void){std::cout<<value<<std::endl;++value;}
  private:
    int value;
};

// main
int main(void){
  Interface<Add> foo;
  foo.print();
  foo.print();
}

The output is

value: 0
value: 1

Therefore the variable value seems to be constructed as 0 by the default constructor. But I don't understand where and when this constructor is called since no object of the derived class is created.

Moreover, let's suppose that I want create value with a different starting value, how can I achieve that using this design pattern? Obviously I could create an init() method in the derived class which is called in the constructor of the base class but it wouldn't work for a type which hasn't a default constructor.

Finally, is it possible to forward some arguments pass to the constructor of the base class to the constructor of the derived class?

jxh

In your source code, you yourself name the base class as Interface. In the object oriented sense, you do not create instances of an Interface, but instances of classes that derive from the Interface. Your code in main erroneously instantiates an Interface rather than the class that derived from it. You can fix this by forcing Interface with properties that make it impossible to instantiate. E.g.:

template<class Imp>
class Interface {
    //...
protected:
    Interface () {} // not accessible except by derived
};

Unlike regular polymorphism, you are not really expected to pass Interface objects around. The Interface provides enforcement of a particular interface by providing the expected methods, and those that derive from the Interface must adopt the expectations of that interface. Your example is a little contrived because the Interface is actually just dispatching to the same named method in the derived. But, a better example is one where the Interface provides an implementation using properties it expects the derived type to provide.

In the example below, we see that Worker inherits the interface of WorkerInterface. But, because of the expectations of WorkerInterface, it is required to implement perform() and wait(). While a pure interface enforces this requirement with pure virtual methods, CRTP enforces this with template expansion.

template <typename JOB>
class WorkerInterface {
public:
    void work () { while (job().wait()) job().perform(); }
private:
    JOB & job () { return *static_cast<JOB *>(this); }
protected:
    WorkerInterface () {}
};

class Worker : public WorkerInterface<Worker>
{
    friend class WorkerInterface<Worker>;
    int state_;
    void perform () { std::cout << "Worker: " << __func__ << '\n'; }
    bool wait () { return state_--; }
public:
    Worker () : state_(1) {}
};

int main ()
{
    Worker w;
    w.work();
}

Now, any class that derives from WorkerInterface will be provided a work() method that will do the "right" thing as long as the derived class provides suitable implementations of wait() and perform().

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How can I call the constructor of the derived class when using CRTP?

From Dev

CRTP with derived class overloading the method

From Dev

Iterate over different CRTP Derived class methods

From Dev

Accessing protected members of derived class with CRTP

From Dev

Move constructor for derived class

From Dev

Overloaded constructor in derived class

From Dev

Error on constructor in derived class

From Dev

Constructor in base and derived class

From Dev

How is a constructor for a derived class supposed to be like in c++ when derived class has added data member

From Dev

c++/cli static constructor of derived class is not called

From Dev

C++ behavior of a default(implicit) copy constructor in a derived class

From Dev

C++: explicit constructor is implicitly called by derived class

From Dev

Declare 'virtual' constructor for base and derived class in c++?

From Dev

How to make Derived class templated on Base class in CRTP

From Dev

Calling the constructor of a base class inside the constructor of its derived class C++

From Dev

Base Constructor Call in Derived Class

From Dev

copy constructor of derived QT class

From Dev

Derived Class Constructor Returning Null

From Dev

Constructor of class derived from QCustomPlot

From Dev

calling a constructor from a derived class

From Dev

Use derived class for template constructor

From Java

How to use aggregated initialization in derived class with CRTP pattern?

From Dev

Static Polymorphism with CRTP: Using the Base Class to Call Derived Methods

From Dev

CRTP - Checking from the base class that the derived one meets requirements

From Dev

CRTP derived class seemingly does not know inherited type

From Dev

Can I forward template arguments of a derived class to the base in CRTP?

From Dev

CRTP derived class seemingly does not know inherited type

From Java

c++ derived constructor when defining function outside of class body - "no default constructor"

From Dev

How can I combine templated derived class in CRTP with derived class expression templates?

Related Related

  1. 1

    How can I call the constructor of the derived class when using CRTP?

  2. 2

    CRTP with derived class overloading the method

  3. 3

    Iterate over different CRTP Derived class methods

  4. 4

    Accessing protected members of derived class with CRTP

  5. 5

    Move constructor for derived class

  6. 6

    Overloaded constructor in derived class

  7. 7

    Error on constructor in derived class

  8. 8

    Constructor in base and derived class

  9. 9

    How is a constructor for a derived class supposed to be like in c++ when derived class has added data member

  10. 10

    c++/cli static constructor of derived class is not called

  11. 11

    C++ behavior of a default(implicit) copy constructor in a derived class

  12. 12

    C++: explicit constructor is implicitly called by derived class

  13. 13

    Declare 'virtual' constructor for base and derived class in c++?

  14. 14

    How to make Derived class templated on Base class in CRTP

  15. 15

    Calling the constructor of a base class inside the constructor of its derived class C++

  16. 16

    Base Constructor Call in Derived Class

  17. 17

    copy constructor of derived QT class

  18. 18

    Derived Class Constructor Returning Null

  19. 19

    Constructor of class derived from QCustomPlot

  20. 20

    calling a constructor from a derived class

  21. 21

    Use derived class for template constructor

  22. 22

    How to use aggregated initialization in derived class with CRTP pattern?

  23. 23

    Static Polymorphism with CRTP: Using the Base Class to Call Derived Methods

  24. 24

    CRTP - Checking from the base class that the derived one meets requirements

  25. 25

    CRTP derived class seemingly does not know inherited type

  26. 26

    Can I forward template arguments of a derived class to the base in CRTP?

  27. 27

    CRTP derived class seemingly does not know inherited type

  28. 28

    c++ derived constructor when defining function outside of class body - "no default constructor"

  29. 29

    How can I combine templated derived class in CRTP with derived class expression templates?

HotTag

Archive