I'm doing a program that manages a collection of items. That can be a Book, a Magazine, a CD or a DVD. Each of those is a class thats inherits the class Item. To store those items I'm using the list template, like this:
list<Item> items;
and this list is inside an object lib of the class Library.
To run through this list I'm doing this:
for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)
Until this point everything's fine. The problem starts when I try to call a method of the derived class inside this loop. example:
for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)
(*i).lib.itens.show();
How can I call those methods?
There are at least two problems here. Firstly, if you do this:
list<Item> items;
then this list really will only contain Item objects; if you try to put in a derived object, the derived part will simply be sliced off.
One solution is to use a list of pointers instead (although you should probably use smart pointers to avoid memory-management issues).
But even then, the second issue is that you shouldn't (in general) be trying to call derived-class-specific methods via pointers to the base class. The whole point of polymorphism is that you should only be dealing in terms of base-class pointers if you're happy to work with functionality that's common to the whole hierarchy (see Liskov substitution principle).
You probably should have defined virtual void show() = 0; in class Item. That would have made the show call legal, but at the same time would have resulted in an error on list<Item>.
The fundamental error is that you can't have something that's "just" an Item, yet list<Item> would attempt to make a list of precisely that. By declaring show as a pure virtual function in Item, the compiler explicitly knows this.
Related
I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.
Is it possible to derive a child from an array Class?
What I am playing with right now is:
Creating an array of Linked Lists
I am building a List class from which I can derive different types of lists (ie. Linear, Circular, Double Linked, etc...
What I would like to do is to extend an array class to make a "arrayOfLists" class. Then I would take the child class and add to it a LinkedList object member.
Is this possible? Am I even thinking of OOP correctly in this instance?
Thank you for your help
The fact that you're talking about it as an arrayOfLists class is a pretty good clue that inheritance is the wrong tool for this job.
Inheritance (public inheritance, anyway) should only be used when the derived class can be substituted for the base class under any possible circumstances. In other words, that an arrayOfLists could be used anywhere a List could be used. Although that might be possible, it seems fairly unlikely.
It sounds to me like what you want is really just an array-like template (e.g., std::vector) instantiated over one of your linked list classes.
I have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.
my dizzyCreature class inherits from both a creature class and a dizzy class. It is also part of a polymorphic collection of creature classes. If I know that my object in the creature class is a dizzyCreature, is there a way to call a function from the dizzy class?
I have tried
creature[2].dizzyCreature::someFunction();
and
dizzyCreature::creature[2].someFunction();
and neither works. Any ideas?
If I understand correctly what you have is something like this: list<Creature*>. This list contains some dizzyCreature instances. On those instances you want to call methods of dizzy class. If this is the objective then you can use dynamic_cast to achieve this. Lets say you have Create* pCreature then you can do:
dizzyCreature* pDizzyCreature = dynamic_cast<dizzyCreature*>(pCreature);
if(pDizzyCreature )
{
pDizzyCreature->someDizzyClassMethod();
}
You need to first check if the class is of the correct type, then cast it using dynamic_cast, as has already been suggested. This solution is elegant since the dynamic cast itself does the type-checking - i.e. it will return NULL if you try to make an invalid cast. (There is no need to use typeid)
As a side note, if I were you, I'd attempt to do whatever it is you're trying to do without multiple inheritance if possible. Multiple inheritance can open up a whole can of worms and is best avoided unless there is no other alternative.
I am using C++ under Ubuntu 11.10 and the latest version of NetBeans. Let's say I have the
following code:
class Node {}
class DerivedNode : public Node {}
class Graph {
vector<Node*> nodes;
}
class DerivedGraph : public Graph { }
At the moment I'm storing DerivedNodes in the DerivedGraph class like this for example:
nodes.push_back(new DerivedNode());
When I need to use specific methods that only apply to DerivedNodes and DerivedGraphs
I am forced to use a dynamic_cast on my Node pointers first.
I would like to be able to have specific methods in DerivedGraph which apply only to DerivedNodes
and avoid the need of casting pointers. I do not mind having to redesign my classes if the end
result is better than what I have.
I am sure there must be a clean and simple method to achieve the same thing I'm trying to do.
Maybe something with specialized templates? Any thoughts on the matter would be greatly
appreciated. I'll also provide any additional information required in the case I haven't been too
clear.
EDIT: I don't have two copies. I wanted to put emphasis on how it looks. I apologize for the presentation. What I want to obtain is:
class DerivedGraph: public Graph {
vector<DerivedNode*> nodes;
}
Are you sure that your interface in Node is appropriate? Sometimes when you find yourself needing to downcast (especially in a case like this where base pointers are stored in a container) that may be a signal that your abstract interface doesn't cover all your needs properly. Often something like the Template Method pattern solves all your needs without needing a downcast at all.
However, assuming that your inheritance model really need work in such a way, what you probably want to do is have virtual methods that get overridden in DerivedGraph for adding and getting nodes. You will have to verify the node type and downcast it in this case.
One final approach is to have two separate containers, one in the parent that contains all nodes that aren't DerivedNode and then another container in DerivedGraph that contains all the DerivedNode. Then you use overridden functions again to determine which container to access depending on your API needs.
Start by not duplicating your data member in the derived class.
Then add virtual member functions that you use to add data to your container. That way you can create instances of derived types in the derived class and add them to the container.
Finally, when you override the virtual function that returns a reference to data in the derived class, use covariant return types.