By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,372 Members | 1,511 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,372 IT Pros & Developers. It's quick & easy.

Getting Base* to act as its actual Derived* type

P: 7
Im thinking i may be attempting some kind of inbuilt cast or something, ideally i just want to overload the right functions so that the following occurs:
-adding a node of the correct type causes the derived class overloaded virtual function to correctly add the node.
-adding a node of the incorrect type defaults to the base class virtual function which reports a general invalid message.

so my goal is to have a Node* type return an identifying pointer of its Derived type so that the correct function is called from the Derived : Diagram type (using that derived pointer as the indentifier for the function signature).

currently the code always prints - "Error: wrong type of node for this type of diagram" - which indicates it is still being passed as a Node* type and not as a Derived : Node* type or atleast, the virtual function in the Base Diagram class is being called in preference to the Derived Diagram versions.

have i got the wrong idea? will this fail no matter how i attempt it?

Note: i understand i can change to Derived::addNode(Node*), to get something that will add the nodes, however i want to enforce restriction on the type of node added to the particular type of diagram

Expand|Select|Wrap|Line Numbers
  1. ERD* diagramERD = new ERD;
  2. DFD* diagramDFD = new DFD;
  3.  
  4. vector<Diagram*> diagramList;
  5. diagramList.push_back(diagramERD);
  6. diagramList.push_back(diagramDFD);
  7.  
  8. vector<Diagram*>::iterator activeDiagram = diagramList.begin();
  9.  
  10. Datastore* myData = new Datastore;
  11. Entity* myEntity = new Entity;
  12.  
  13. Node* myNodeData = new Datastore;
  14. Node* myNodeEntity = new Entity;
  15.  
  16. (*activeDiagram)->addNode(myData->getMyType());
  17. (*activeDiagram)->addNode(myEntity->getMyType());
  18. (*activeDiagram)->addNode(myNodeData->getMyType());
  19. (*activeDiagram)->addNode(myNodeEntity->getMyType());
  20. (*activeDiagram)->addNode(dynamic_cast<Datastore*>(myData));
  21. (*activeDiagram)->addNode(dynamic_cast<Entity*>(myEntity));
  22. (*activeDiagram)->addNode(dynamic_cast<Entity*>(myData));
  23. (*activeDiagram)->addNode(dynamic_cast<Datastore*>(myEntity));
  24.  
Expand|Select|Wrap|Line Numbers
  1. class Node {
  2. public:
  3.   virtual void checkMyType() {
  4.     cout << "I am a Node";
  5.   }
  6.   virtual Node* getMyType() {
  7.     return this;
  8.   }
  9. };
  10.  
  11. class Datastore : public Node {
  12. public:
  13.   virtual void checkMyType() {
  14.     cout << "I am a Datastore";
  15.   }
  16.   virtual Datastore* getMyType() {
  17.     return this;
  18.   }
  19. };
  20.  
  21. class Entity : public Node {
  22. public:
  23.   virtual void checkMyType() {
  24.     cout << "I am an Entity";
  25.   }
  26.   virtual Entity* getMyType() {
  27.     return this;
  28.   }
  29. };
  30.  
  31. class Diagram {
  32. public:
  33.   virtual void addNode(Node *newNode) {
  34.     cout << "Error: wrong type of node for this type of diagram" << endl;
  35.   }
  36. };
  37.  
  38. class DFD : public Diagram {
  39. public:
  40.   virtual void addNode(Datastore *newDatastore) {
  41.     cout << "DFD::Adding ("; newDatastore->checkMyType(); cout << ") to nodeList" << endl;
  42.   }
  43. };
  44.  
  45. class ERD : public Diagram {
  46. public:
  47.   virtual void addNode(Entity *newEntity) {
  48.     cout << "ERD::Adding ("; newEntity->checkMyType(); cout << ") to nodeList" << endl;
  49.   }
  50. };
  51.  
May 24 '07 #1
Share this Question
Share on Google+
1 Reply


weaknessforcats
Expert Mod 5K+
P: 9,197
I am curious why you are doing this. I would have thought you would just have a vector of base class pointers and let it go at that.

However, if you need to get the exact type of the derived object, I suggest you design your classes for the Visitor design pattern.

I don't have time today to go through the pattern, but if you have a copy of the Design Patterns book by Erich Gamma, et al. Addison-Wesley 1994, the Visitor pattern is on page 331.

Visitor allows you to add methods to derived classes that are not the base class methiods and be able to call those methods by using a base class pointer.

In your case, you create a DFDVisitor (derived from DiagramVisitor) and call the Diagram Accept method that takes a DiagramVisitor pointer.

The Diagram Accept calls the Diagram DoAccept and passes along the DiagramVisitor pointer.

Diagram DoAccept is overriden by DFD DoAccept which uses the DiagramVisitor pointer to call VisitDFD in the DiagramVisitor class using the "this" pointer of the Diagram (which is really a DFD pointer). VisitDFD is overriden by DFDVisitor and so are really calling VisitDFD using a DFD*. Now you can run any methods on the DFD class regardless of whether they are in the Diagram class or not.

--and you never need to know the type of the pointer.

Check it out.
May 24 '07 #2

Post your reply

Sign in to post your reply or Sign up for a free account.