473,394 Members | 1,806 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Getting Base* to act as its actual Derived* type

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
1 1170
weaknessforcats
9,208 Expert Mod 8TB
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

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

Similar topics

6
by: Abhijit Deshpande | last post by:
Is there any elegant way to acheive following: class Base { public: Base() {} virtual ~Base() {} virtual void Method() { cout << "Base::Method called"; return; } };
12
by: Tim Clacy | last post by:
Your expertise will be appreciated... Here's a general templatised class; all specialisations of this class should have a pointer to a specialisation of the same, templatised type: ...
8
by: Bryan Parkoff | last post by:
I find an interesting issue that one base class has only one copy for each derived class. It looks like that one base class will be copied into three base classes while derived class from base...
8
by: Dev | last post by:
Hello, Why an Abstract Base Class cannot be instantiated ? Does anybody know of the object construction internals ? What is the missing information that prevents the construction ? TIA....
5
by: Dimitry | last post by:
I am trying to make the following: struct Base { char param; }; class Derived1 : public Base { public:
11
by: Frederic Rentsch | last post by:
Hi all, If I derive a class from another one because I need a few extra features, is there a way to promote the base class to the derived one without having to make copies of all attributes? ...
6
by: Me | last post by:
I need to be able to acces non-virtual members of sublcasses via a base class pointer...and without the need for an explicit type cast. I thought a pure virtual getPtr() that acts as a type cast...
2
by: kasthurirangan.balaji | last post by:
Hello, template<class Base> class Derived : public Base { }; By using template, i understand the actual base type will be deduced at compile time. Moreover, class Derived will consist only...
10
by: blangela | last post by:
If I pass a base class object by reference (likely does not make a difference here that it is passed by reference) as a parameter to a derived class member function, the member function is not...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.