C++ call std::list of objects instead of C linked list Can this be made more C++ a like with std::list or something so the Clink class is not needed?

I have a dynamic list of objects, and the number of them could change during runtime.

The expected output in no specific order. As an example 'Cb' runs before 'Ca':

link-contructed
Ca-contructed
Cb-contructed
Cb-run
Ca-run
Ca-destructed
Cb-destructed
link-destructed


I would like the program to be more C++ like with std::list or something. I have looked at std::forward_list but can not really see how it should be used. All examples I could find is about std::list&lt;int&gt;. My Ctask needs to have next in it and Clink needs to know which objects is used. Not so generic. Here is the mixed C/C++ program which does the expected:

/*
vim: ts=4 :
g++ -lstdc++ -o linked linked.cpp &amp;&amp; ./linked
*/

#include &lt;iostream&gt;
using namespace std;

class Ctask {
public:
    Ctask *next = NULL;
    Ctask(void) {}
    virtual ~Ctask(void) {}
    virtual void run(void) = 0;
};

/* --------------------------------- */

class Clink {
public:
    Clink(void) {
        cout &lt;&lt; "link-contructed" &lt;&lt; endl;
    }
    ~Clink(void) {
        Ctask *temp;
        while (temp = head) {
            head = head-&gt;next;
            delete temp;
        }
        cout &lt;&lt; "link-destructed" &lt;&lt; endl;
    }
    void run(void) {
        Ctask *temp = head;
        while (temp) {
            temp-&gt;run();
            temp = temp-&gt;next;
        }
    }
    void add(Ctask *newnode) {
        if (tail)
            tail-&gt;next = newnode;
        else
            head = newnode;
        tail = newnode;
    }
private:
    Ctask *head = NULL;
    Ctask *tail = NULL;
};

/* --------------------------------- */

class Ca: public Ctask {
public:
    Ca(void) {
        cout &lt;&lt; "Ca-contructed" &lt;&lt; endl;
    }
    ~Ca(void) {
        cout &lt;&lt; "Ca-destructed" &lt;&lt; endl;
    }
    void run(void) {
        cout &lt;&lt; "Ca-run" &lt;&lt; endl;
    }
};

class Cb: public Ctask {
public:
    Cb(void) {
        cout &lt;&lt; "Cb-contructed" &lt;&lt; endl;
    }
    ~Cb(void) {
        cout &lt;&lt; "Cb-destructed" &lt;&lt; endl;
    }
    void run(void) {
        cout &lt;&lt; "Cb-run" &lt;&lt; endl;
    }
};

/* --------------------------------- */

int main(void) {
    Clink link;
    link.add((Ctask *)new Ca());
    link.add((Ctask *)new Cb());
    link.run();
    return 0;
}
Based on your answer and the comments from @user673679, with some modifications:


Removing using namespace std.
Using unique_ptr to transparently handle object allocation and deallocation. Remember to create items with make_unique.
forward_list is just fine for a FIFO queue.


Note that I don't use a range-based for loop because I only iterate the list once (run function and remove element).

#include "ctask.h" // Ctask, Ca and Cb definitions
#include &lt;forward_list&gt;
#include &lt;iterator&gt;
#include &lt;memory&gt;

class TaskQueue {
public:
   TaskQueue() :
     _tasks(),
     _last( _tasks.before_begin() )
   {
   }

   ~TaskQueue() = default;

   void add( std::unique_ptr&lt;Ctask&gt;&amp;&amp; t ) {
     _last = _tasks.insert_after( _last, std::move(t) );
   }

   void run_all() {
     task_list::iterator prev = _tasks.before_begin();
     task_list::iterator curr = _tasks.begin();
     while( curr != _tasks.end() ) {
        (*curr)-&gt;run();
        curr = _tasks.erase_after(prev);
     }
     _last = prev;
   }

private:
   typedef std::forward_list&lt;std::unique_ptr&lt;Ctask&gt;&gt; task_list;
   task_list           _tasks;
   task_list::iterator _last;
};

int main(void) {
    TaskQueue queue;
    queue.add(std::make_unique&lt;Ca&gt;());
    queue.add(std::make_unique&lt;Cb&gt;());
    queue.run_all();
    return 0;
}


Edit: I realized that you can make run_all more readable since you are basically removing all the elements from the queue, so that the while loop doesn't actually depend on _last value. The simplified function would be:

   void TaskQueue::run_all() {
     while( !_tasks.empty() ) {
        _tasks.front()-&gt;run();
        _tasks.pop_front();
     }
     _last = _tasks.before_begin();
   }