0

Hello and thanks in advanced.

Here is my issue. I have these classes:

-class Date -class Contract -class Employee -class Node -class List

All of the classes derive from this class BaseObject. It has this code:

#ifndef BASEOBJECT_H
#define BASEOBJECT_H
#include<iostream>
using namespace std;

class BaseObject{
public:
virtual string toString() const=0;
virtual BaseObject* clone() const=0;
};

ostream& operator << (ostream&, objetoBase&);


#endif  /* BASEOBJECT_H */

That's all it has. I'm skipping the operator << implementation. Now, I'll explain the idea

Class Date has just elemental attributes (int day, int month, int year). Class Contract has two class Date pointers so Contract is related to Date by composition. Class Employee has an association with one Contract handled with pointer.

Class Node has two attributes: the first is a pointer to a Node which contains an ObjectBase instance called Data, the second one is a pointer to another Node instance called nextNode.

Class List handles the node pointers in a simple list.

My question: When I am looking for an Employee in the list and use a Find() function to have acces to the Data contained in Node, it now just shows the methods created in BaseObject! How can I solve this? I leave the code to you. The first and current are nodes.

BaseObject * List :: find (string id) {
        if (first == NULL)
            return NULL;
        else
        if (first-> getData () -> == getId() id) //This line is underlined in compiler
            return first-> getData ();
        else {
            current = first;
        if (current-> getNextNode () == NULL)
            return NULL;
        else {
        while (current-> getNextNode () -> getNextNode ()! = NULL && Current-> getNextNode () -> getData () -> getId ()! = id) {
            current = current-> getNextNode ();}
        if (current-> getNextNode () -> getData () -> getId () == id)
            return current-> getNextNode () -> getData ();
        else
            return NULL;
        }
    }
}

The underlined code makes the error. When I use the compiler and put the "->" sign it only shows BaseObject methods Clone() and toString() and I want to make use of the Employees methods although it is now a BaseObject pointer with an Employee instance within it.

Please help me if I expressed me well.

  • Have you considered the `List` class and its subordinate `Node` class might be as much, if not *more* beneficial to document for this question than the two-member abstract object base class provided? Ex: `getData()` we can only guess as to its returned value. Further, you clearly have an outright syntax error, not just a logic error. You may want to address that first. – WhozCraig Apr 12 '13 at 05:31
  • Also, **almost** every time you have linked-list code that logic of this form: `current->getNextNode()->getNextNode()` you should question the design. consider the design. – WhozCraig Apr 12 '13 at 05:37
  • So, you are asking for me to copy the rest of the list and node members code? And for the syntax, don;t worry it's just a logic error. Thanks. – Ditmark Rivas Apr 12 '13 at 05:37
  • Ok then, discounting the errors, you are purposely using a BaseObject interface paradigm for interface abstraction reasons. The implementor is responsible for filling out those methods, and only those methods, by this design. but per the design you have no guarantees the BaseObject being pointed to by your search result is indeed an Employee. It could be something (anything) else derived from BaseObject. *This is the purpose of abstract base interfaces*. If you need an Employee list you can certainly wrap this one with a protective shell that ensures only Employee instances are uses. – WhozCraig Apr 12 '13 at 05:41
  • Yes, certainly. The compiler does not know if the instance pointed to with the BaseClass pointer is an Employee instance. That's my problem. Do you know something to solve it? – Ditmark Rivas Apr 12 '13 at 05:48
  • 1
    Surely. `dynamic_cast<>`, but don't just use it; make sure you know *how to use it properly*, which is another subject. Search SO, there are *tons* of examples and proper how-to's. And it still begs the question to *you*. Why are you just storing BaseObject pointers if you need an Employee list? Honestly the question goes beyond even that. Why *aren't* you using a `std::vector` or `std::list` ? Anyway hope it helped. – WhozCraig Apr 12 '13 at 05:51
  • Ok. Thanks for your help. It's a light in the dark. – Ditmark Rivas Apr 12 '13 at 05:53
  • @WhozCraig You should make an answer out of that comment. – Agentlien Apr 12 '13 at 05:56

1 Answers1

0

You can change a little your implementation and create a Comparable interface and all of your BaseObject's are comparable.

Or you can pass a "comparator" function in your find method. In this function you will need to do some casts to verify if your instance is an Employer and compare de Id's.

I hope this can help.

Pedro

Pedro Gandola
  • 196
  • 1
  • 11
  • Thanks. I really don't know how to handle inheritance form BaseObject. But, recently, I learned something about casting. Maybe, this is the reason why the problem is envolving BaseObject because I don't know how to implement it well. – Ditmark Rivas Apr 15 '13 at 03:24
  • You can have a class called *Searchable*, it has an abstract method called *search* that receives a *map* with parameters. If your *BaseObject* extends from *Searchable* you will force that all your concrete classes (ex: Employer) implements the method *search*. **Example:** **bool Employer::search(const map& params){ if (map.get("id") == id){....} }** After this you can have in your *find* method something like: **stl::map params; params.insert(id)... obj.search(map);** This is called polymorphism. http://www.cplusplus.com/doc/tutorial/polymorphism/ – Pedro Gandola Apr 15 '13 at 04:03