Inheritance, containers with base type, typecasting

hello,
I have a class Node, and another one called TransformationNode : public Node

in a function called updateTransform, I iterate trough a vector in the base class vector<Node*> nodes.

In the base class there are no such functions, lets say void addVec(); and TransformationNode* updateTransfrom();

and updateTransfrom() is something like this...

1
2
3
4
5
6
7
8
9
10
11
TransformationNode* updateTransfrom() {
  auto beg = nodes.begin();
  auto end = nodes.end();

  while(beg != end) {
    TransformationNode* tmp = static_cast<TransformationNode*>(*beg);
    tmp->addVec();
    beg++;
  } 
  return tmp;
}



I don't want to do type cast alot, is this the only way of doing this ? How do I tell my compiler that, "nodes" vector is already containing TransformationNode* ?

And I have an other very similar issue,
I have a functon called Graph* getGraph() in base, and a member Graph* mGraph
However, implementation in TransformationNode class must be somethig like this SceneGraph* getGraph(); and the member mGraph's type also must be TransformationNode*
I get around this issue by type casting the pointer returned by getGraph() to a TransformationNode* pointer

I wanted to know if my design is problematic or there is a better solution to these kind of problems.
And if you know any, good books or articles about this kind of usage of the c++ and object oriented design

thank you for taking your time.
If you know that all nodes in the vector are of type TransformationNode why not declare the vector as vector<TransformationNode*>?
I don't want to do type cast alot, is this the only way of doing this ?


No. If your container contains Nodes, then you should treat them as Nodes. You should not treat them as TransformationNodes.

If this container can only have TransformationNodes in it, then make it a container of TransformationNodes. ie: vector<TransformationNode*>


Another (better) option would be to only use things that are exposed to Node. This might mean making addVec a pure virtual function in Node. But only do that if it makes sense!
I believe that I miss direct you by not adding signature fully,
TransformatinoNode* TransformationNode::updateTransform()

I am trying to handle these nodes in a derived class and there will be other classes deriving from Node class such as CameraNode so what I can think of was casting these pointers

All nodes no matter what type they are, share some generic properties and functionalities, such as a parent, so there must be a container which contains child nodes.

here is the .h files of the two classes, this might help you to understand my problem a little more
Last edited on
Last edited on
I figured it wasn't as simple... but the problem remains the same. You have this container of nodes and are trying to treat all of the nodes as if they are transformation nodes.

The original problem:

1
2
3
4
5
6
7
8
9
10
11
TransformationNode* updateTransfrom() {
  auto beg = nodes.begin();
  auto end = nodes.end();

  while(beg != end) {
    TransformationNode* tmp = static_cast<TransformationNode*>(*beg);
    tmp->addVec();
    beg++;
  } 
  return tmp;
}


addVec is something specific to TransformationNode, right? So this code will fail horribly if 'nodes' contains any other kind of nodes, because this code assumes that all nodes are TransformationNodes.

There are 3 solutions I can think of:

1) Make addVec a virtual function in Node so you don't need to downcast to a TransformationNode
or
2) Make a separate container of TransformationNodes (in addition to your more generic Node container)
or
3)downcast with dynamic_cast, see if you actually have a TransformationNode or not, and only call that function if you do.


All options have their pros and cons. Which you chose depends on how you want your program structured.
I have a functon called Graph* getGraph() in base, and a member Graph* mGraph
However, implementation in TransformationNode class must be somethig like this SceneGraph* getGraph(); and the member mGraph's type also must be SceneGraph*
I get around this issue by type casting the pointer returned by getGraph() to a TransformationNode* pointer


As a result of my research on the second subject (the one I quoted above), I found something called covariant return types
beriefly it says:

In an overridden method that returns a pointer or a reference to a class, you are allowed to change the return type to a derived class instead


http://www.tolchz.net/?p=33

I believe that there is a design pattern or some other way to solve the first problem I encountered also.
And thank you for your recommendations. It seems that the best thing is not to mix node and transformation node unless I find out a better and cleaner solution
Last edited on
Topic archived. No new replies allowed.