Manuel wrote:
[color=blue]
> Hi!
>
> If I've a vector filled with abstract classes,[/color]
You cannot fill a vector with classes, only with objects. You also can't
fill it with instances of abstract classes, so I assum you are talking
about pointers.
[color=blue]
> can I push in it the derived classes too?[/color]
Yes.
[color=blue]
> Even if derived classes have new methods?[/color]
Yes.
[color=blue]
> I've done some experiments, and it seem I can push the derived classes,
> but I can use them only calling the methods declared in abstract class
> (the new methods declared only in derived classes return an error).[/color]
Well, how would the compiler know at compile time (i.e. when it sees your
function call) which actual class the object you are accessing will be at
runtime? How should it know which member functions are available?
[color=blue]
> Please take a look to my code (hey, this is not an homework!
> I'm studying C++ to port this opensource project from python to C++
>
http://www.makehuman.org):
>
> This is my abstract class:
>
> --------------------------------------------
> class mhwidget
> {
>
> public:
> virtual void draw()= 0;
> virtual ~mhwidget() {}
>
> };
> --------------------------------------------
>
> In another file, I've defined a vector for this class:
>
> --------------------------------------------
> std::vector<mhwidget*> widgetList;[/color]
So it is - as I assumed - a vector of pointers to mhwidget.
[color=blue]
> --------------------------------------------
>
> I fill this vector, and use the "draw()" method,
> in this way:
>
> --------------------------------------------
> //Put widget into container
> void mhcontainer::addWidget(mhwidget* w)
> {
> widgetList.push_back(w);
> }
>
> //Draw all widgets
> void mhcontainer::drawAll()
> {
>
> std::vector<mhwidget*>::iterator it = widgetList.begin();
> while(it != widgetList.end())
> {
> (*it++)->draw();
> }
> }
> --------------------------------------------
>
> I've written an example of derived class (this is only the header):
>
> ---------------------------------------------
> class square : public mhwidget
> {
> public:
> virtual void draw();
> };
> ---------------------------------------------
>
> and this seem to work (from application/client code):
>
> ---------------------------------------------
> mhcontainer contn;
> contn.addWidget(new square);
> contn.drawAll();
> ---------------------------------------------
>
> but I'm not sure it's a clean C++ code.[/color]
This looks fine.
[color=blue]
> If I add a new method in "square" and try to use it, like
> while(it != widgetList.end())
> {
> (*it++)->draw();
> (*it++)->newMethod();
> }[/color]
Are you sure that you want to call draw() only for every second object?
[color=blue]
> it return an error, but this make sense...[/color]
What is the programm supposed to do with those objects that are not of
dynamic type "square"? If you're accessing the object through mhwidget's
interface, only that is available.
If you want newMethod() be called where draw() is called, simply call it
from square::draw().
An alternative (which is in many situations considered as a design flaw in
C++) would be to use a dynamic cast, like:
while(it != widgetList.end())
{
(*it++)->draw();
square* sq = dynamic_cast<square*>(*it++);
if (sq)
sq->newMethod();
}