Deriving from concrete types like std::list
In the 3rd edition of "The C++ Programming Language", Stroustrup
writes in section 25.2 about concrete types
"Classes such as vector, list [...] are concrete [...]
Also, [...] none are intended as a base for derivation."
and two pages later
"A class that does this well is rarely a good candidate for
the creation of different but related classes through public
derivation."
Some of the following arguments seems valid, but still I don't see why
I shouldn't derive a new class from list.
As a C++ learning project I'm re-implementing a simple interpreter I
wrote in C almost 20 years ago.
I have an abstract base class Stmt from which I derive several
concrete statement types, one of which is the StmtList. I want the
StmtList to inherit from Stmt and from list <Stmt *>, so I can call
push_back() on it in the parser or iterate through it to execute the
statement list. Currently, I have something like this, which works
perfectly and, IMHO, looks quite nice:
class Stmt {
public:
virtual void exec() = 0;
};
class WhileStmt : public Stmt {
Expr *cond;
Stmt *stmt;
public:
virtual void exec() {
while (cond->eval())
stmt->exec();
}
};
class StmtList : public Stmt, public std::list <Stmt *> {
public:
virtual void exec() {
const_iterator it;
for (it = begin(); it != end(); ++it)
(*it)->exec();
}
};
// in the parser
stmt_list->push_back(stmt);
Is this, according to Stroustrup, the wrong approach? Instead of
deriving I could have a member of type list <Stmt *> in class StmtList
but iterating would look more cumbersome and I had to implement my own
push_back() that calls push_back() for that list member, etc. After
all, a statement list *is* a list. Shouldn't I express this
relationship by derivation?
urs