here are the classes which my question is about
class Graph {}
class SceneGraph : public Graph {}
class Node {
public:
virtual Node* getNode(int index) { return mNodeList[index]; }
protected:
vector<Node*> mNodeList;
Graph* mGraph;
}
class TransformationNode : public Node {
public:
TransformationNode* getNode(int index) { return static_cast<TransformationNode*> (mNodelist[index]); }
void _update() {
auto beg = mNodeList.begin();
auto end = mNodeList.end();
while (begin != end) {
TransformationNode* node = static_cast<TransformationNode*> (*beg);
node->_update();
}
}
private:
bool mUpdated;
SceneGraph* mGraph;
}
First of all, I want to talk about the problems I solved. They may helps others. And you can confirm me if I am right ^^
Can I override a function with a different return type ?
Node* getNode(int index) became TransformationNode* getNode(int index)
Yes as long as return types are covariant : http://www.tolchz.net/?p=33
Can I override a member ?
I don't know about overriding but a variable with the same name in the derived class will hide the one in the base class
And there is the problem I really want to get around some how
In the TransformationNode class I did many (IMHO) avoidable type casting from base class to derived one. I definitely know that all the elements in the mNodeList vector are TransformationNodes but to process mNodeList I have to type cast them.
The inheritance is correct I mean TransformationNode is a Node
mNodeList holds child nodes of the node and it can not have a copy in the derived class which holds typecasted version of Nodes
And finaly I can even use reinterpered_cast if static_cast is more costly. Can you inform me about cost of these operations ? are they really big performance issues ?
assert (dynamic_cast)... kind of precaution has already been taken.
briefly I want my compiler to know that mGraph is actually a SceneGraph* and mNodeList holds TransformationNode* this helps me to avoid lost of type casting.
Thank you for taking your time
1) is correct, you can indeed override (virtual!) base functions if the return type is more derived.
Ad 2): indeed, you cannot "override" members. Redesign the base class if you need more flexible overridable behaviour.
static_cast is a static operation that is resolved at compile time, so much like reinterpret_cast it doesn't have any "cost".
As #Seth suggests in the comment, it might be an option to move the container. Ask yourself, can there ever be an abstract Node, or is every node actually of some derived concrete type? Perhaps you could make Node abstract:
struct Node { Node * getNode(size_t index) const = 0; };
struct TransformNode : Node
{
TransformNode * getNode(size_t index) const { return m_nodes[index]; }
private:
std::vector<TransformNode *> m_nodes;
};
Put the entire interface into the base class, but only implement it in each concrete class.
Related
Recently, I am learning Inheritance and Polymorphism in C++.
I made three classes: Node, uni_dir_Node(uni-direction Node), and bi_dir_Node(bi-direction Node).
Here is my code:
class Node {
protected:
string name;
Node* next;
virtual void connect(Node* _Node) = 0;
};
class uni_dir_Node : public Node {
void connect(Node* _Node) {
this->next = next;
}
};
class bi_dir_Node : public Node {
Node* previous;
void connect(Node* next_Node, Node* previous_Node) {
this->next = next;
this->previous = previous_Node;
}
};
int main()
{
Node* head = new bi_dir_Node;
return 0;
}
Of course there is a compiler error in this code.
My question is, the function connect() in class uni_dir_Node has one parameter but for the function connect() in class bi_dir_Node has two parameters. How do I keep this inheritance structure and make it legal?
Is there any good way to solve this problem?
As others have said, the problem is that bi_dir_Node doesn't have a void connect(Node* _Node) method.
Conceptually, what's going on is that inheritance indicates an "is a" relationship. Saying that bi_dir_Node inherits from Node means that bi_dir_Node is a Node, so anything that a Node can do, a bi_dir_Node can do.
You're trying to say that bi_dir_Node is a Node but that it can't do everything a Node can: specifically, it can't Connect with a single argument.
The solution is to either provide a single-argument Connect for bi_dir_Node or to remove or redesign the inheritance structure. For example, in C++, templates may be a better approach: you can make uni_dir_Node and bi_dir_Node completely separate (not part of the same inheritance hierarchy) and write template classes and template functions that are generic enough to operate on both.
As says nwp, to have polymorphism, you need to have functions with the same prototypes in the derived classes.
By prototype, it means :
same return type
Same parameter list
const keyword at the end of the prototype must be present on derived if present on base method
same method name of course
This is because all functions need to be called the same way and same semantic whether it is a base or derived object.
virtual key word must be put on the base class method prototype.
The virtual behavior is inherited. So it can be put or not on derived class overriden methods.
Advanced stuff - not often useful :
Since C++ 98 (prehistory !), if a base class method is
Base * Method();
The derived method can be :
Derived * Method();
This is because Derived* IS A KIND of Base*
Hope it clarifies
I have a type heirarchy:
class Object {
...
};
class Node : public Object {
...
};
class Leaf : public Object {
...
};
class Something : public Node {
...
};
class SomethingElse : public Leaf {
...
};
In other words, absolutely every class inherits Object either directly or indirectly.
The constructor for every object is in the following format:
ClassType(Object * parent)
However, by design only a Node can be a parent, while a Leaf is a terminating node;
In the moment, in every constructor I am doing the following:
Node * p = dynamic_cast<Node *>(parent);
if (p) p->adopt(this);
else qDebug() << "for some reason cast failed";
So, my primary question is this - considering that every parent object can only be a Node or derived from Node, is it safe to use static_cast instead? Naturally, the primary concern is performance, right now I get about 4 million nodes created per second, which does not seem like a bottleneck, but still, this is barebone hierarchy, as it is populated with more logic it will get slower, so if I can get rid of the dynamic_cast it will be a good thing.
I have verified that for Something s it will be true that &s == static_cast<Node *>(&s) == dynamic_cast<Node *>(&s) but I am not sure whether I can "put all my eggs into that basket" so to speak - is it guaranteed that I can "blindly" reuse the address of every directly or indirectly derived from Node class as a Node * as long, regardless of whether it is created on the stack, Object * s = new Something, Node * s = new Something, Something * s = new Something or any of the many possible variations?
My secondary question is whether this design is a good idea. I do realize that it is somewhat pointless to pass an Object * for parent, considering that only Nodes can be parents, but the Node itself stores its children internally as Object * because not all children derive from Node. Naturally, any recommendations to make this more elegant are welcomed.
If You are worying about this cast, maybe you should define parent member as Node? Then You will never need to cast. Also you will be sure you always use Node as a parent.
Now, for some logical reasons you know that a parent will always be a Node, hence you should use static_cast.
Problem is, it's really hard to debug this code if your assumption fails. What you might want to do is something like this:
#ifdef NDEBUG
Node * p = static_cast<Node*>(parent);
#else
Node * p = dynamic_cast<Node *>(parent);
assert(p);
#endif
p->adopt(this);
This can be easily achieved with boost::polymorphic_downcast.
Node * p = boost::polymorphic_downcast<Node*>(parent);
My professor of languages at university told us to avoid as much as possible dynamic cast and it is something that I try to do every time I have to develop a complex hierarchy.
That being said, if you know exactly that Parent points to a Node then a static cast is safe.
A pointer to member of some class D can be upcast to a pointer to
member of its base class B. This static_cast makes no checks to ensure
the member actually exists in the runtime type of the pointed-to
object.
In short, if you know that D will always be derived from B, using static_cast is safe.
If performance is one of your concerns, I would suggest simplifying (flatten) your hierarchy.
If you know that parent is a Node, then the static_cast does the right thing.
But if you know that parent is a Node, then why not change the constructors (and probably whatever parent pointer you keep inside Object) to reflect this reality?
You can create a fast (O(1), one virtual call) version for your cast if you create a virtual function which transforms object to node if it is a node. In case of succes you get a node* and in case of a failure you get nullptr. This cast is hidden inside the mechanism of the virtual call and thus type safe.
class node;
class object {
// other things
public:
node const* as_node() const { return 0; }
node* as_node() { return 0; }
};
class node {
// other things
public:
node const* as_node() const { return this; }
node* as_node() { return this; }
};
When you do downcast (from Object to Node), you have to use dynamic_cast. For the other way around (Node to Object), static_cast is fine.
The fact that you have to downcast using dynamic_cast indicates a problem in design.
I do not know details, but you could change constructors. Instead of taking Object* parent, you can take Node* parent and Leaf* parent.
So, change :
struct A
{
A( Object* parent );
};
to :
struct A
{
A( Node* parent );
A( Leaf* parent );
};
also, instead of pointers, I would use references.
Another option is to implement the adopt method in all classes. In classes that do not need it, will use default no-op operation, and override it in classes that actually do something. Then you do not need to cast.
class Object {
virtual void foo(){ /*no-op*/ }
};
class Node : public Object {
virtual void foo(){ /* hi-ho */ }
};
class Leaf : public Object {
// uses default foo
};
void callFoo( Object & obj )
{
// no need to cast
obj.foo();
}
I have a skeleton of a project I need to implement a Doubly Linked List (no using stl) and the way the class is implemented is to inherit all is methods from a struct like so:
struct IDoubleList {
virtual IDoubleNode * getHead() = 0;
virtual IDoubleNode * getTail() = 0;
virtual void setHead(IDoubleNode * head) = 0;
virtual void setTail(IDoubleNode * tail) = 0;
virtual void addBack(int value) = 0;
};
class DoubleList : public IDoubleList {
public:
virtual IDoubleNode * getHead();
virtual IDoubleNode * getTail();
virtual void addBack(int value);
virtual void setHead(IDoubleNode * head);
virtual void setTail(IDoubleNode * tail);
private:
DoubleNode* m_Head;
DoubleNode* m_Tail;
};
As you can getters and setters use the struct, not the class to return/pass pointers. My question is how can I use the methods in he object m_Tail is pointing to. I tried using m_Tail.setNext(newNode); where setNext is method in the DoubleNode class but that says the expression must have a class type.
Also when I return/pass a DoubleNode* should I be casting or something to IDoubleNode*? or maybe its the other way around?
PS been a while since ive used C/C++, maybe I'm forgetting something about function pointers? idk so lost right now
Thanks in advanced, let me know if you need any more info
First of all, it should be m_Tail->setNext(newNode), not m_Tail.setNext(newNode) because m_Tail is a pointer. You could also do (*m_Tail).setNext(newNode), the point is that you have to dereference the pointer somehow.
No, you do not need to cast a pointer from a DoubleList to IDoubleList when passing it to a function expecting an IDoubleList. This is because every DoubleList is a IDoubleList, so no casting is required. Also, the only difference between a struct and a class is the default access level of the members (public for a struct, private for a class).
First, you should make IDoubleNode a base class of your DoubleNode (if you haven't already). Then you need to dynamic_cast<DoubleNode*>(ptr) in the methods taking a IDoubleNode* to get hold of your DoubleNode (and e.g. throw an exception if this fails). Also, make sure you use pointer notation when accessing members of pointers, i.e. ptr->member instead of ptr.member: the latter notation only works for objects. You could use (*ptr).member but this is unnecessarily contrived.
Finally, don't forget to tell your instructor to set reasonable assignments next time because this is an entirely pointless exercise: this is bad example for using object oriented approaches (you can subvert type-safety via the base class interface) and it is pointless to use object oriented approaches in a data structures class.
I have a vector with pointers of type Vehicle. Vehicle is the base class and there are many derived types like MotorCycle, Car, Plane, etc. Now, in my program there comes a point where I need the derived type while traversing the vector. Each Vehicle class has a GetType() function which returns an int which tells me what the derived type is (motorcylce, car, plan). So, I can use a dynamic cast to downcast to the derived type from the base class pointer. However, I need to have a giant if statement everytime I need the derived pointer
if(vehicle_ptr->GetType() == PLANE)
Plane *ptr = dynamic_cast<Plane*> vehicle_ptr;
else if (vehicle_ptr->GetType() == MOTORCYCLE)
MotorCycle *ptr = dynamic_cast<MotorCycle*> vehicle_ptr;
..and on and on.
Is there a way to have a function or some trick I can call that would save me from the giant if statement everywhere? Like ::GetDerivedPtr(Vehicle *ptr). Would a template class help here? (never used them before) Sorry, my C++ is a bit rusty and I did search but these terms bring up too much material to find what I'm looking for. Thanks.
It looks like you've manually tried to recreate polymorphism. You don't need a type member. This is almost always a bad idea. Use polymorphism and virtual functions.
When you have a vehicle pointer v and do
v->function();
It will call the proper function for whatever type (Plane, Train, or Automobile) that the pointer actually points to if function is a virtual function. What you're doing is already handled by the language.
So:
class A {
public:
virtual void f() {cout << "A";}
};
class B : public A {
public:
virtual void f() {cout << "B";}
};
int main(){
A *a;
B b;
a = &b;
a->f();
}
The above snippet will print B.
I second the idea that you need some virtual function and a common base type. Imagine that there is some way to get the pointer which has the correct type. What will you do with it then? You'll have to make a giant switch anyway, because you call specific functions for each of your specific types.
One solution would be to invent a name for the operation you are trying to execute, and put its implementation as a virtual function at each specific Vehicle class. If the operation accepts different parameter for each of the cases, the parameters have to be packed into a special polymorphic structure/class, but here maybe the Visitor pattern is a more generic solution.
First check whether what you're going to do can be done simply via virtual functions in class Vehicle, overridden by each derived class.
If not, then consider the Visitor Pattern.
Cheers & hth.,
dynamic_cast will check the type itself (you don't need your own variable for this). You can do the following instead:
Plane *plane_ptr = dynamic_cast<Plane*>(vehicle_ptr);
if(plane_ptr != NULL)
{
// Do stuff with 'plane_ptr' that you couldn't do with 'vehicle_ptr'
}
I don't really see how creating a function to do the cast would help because you still need to class specific code anyway (and the function would have a fixed return type, so the closest you could get is something like the 'dynamic_cast' call, which is pretty much a standard function anyway).
Use Visitor based dispatching. Observe that not a simple cast of any kind is required in the follwing (somewhat trivialized) example:
// simple cyclic visitor
class VehicleVistor {
public:
// add overload for each concrete Vehicle type
virtual void Visit(class Motorcycle&) {};
virtual void Visit(class Plane&) {};
virtual void Visit(class Car&) {};
};
class Vehicle {
public:
virtual Accept(VehicleVisitor&) = 0;
};
class Car : public Vehicle {
public:
virtual Accept(VehicleVisitor& pVisitor) {
pVisitor.Visit(*this);
}
};
// and so on...
At some point of you program you need to retrieve all instances of, say Motorcycle:
class MotorcycleExtractingVisitor : public VehicleVisitor {
std::vector<Motorcycle*> mMotorcycles;
public:
void operator()(Vehicle* pVehicle) {
pVehicle->Accept(*this);
}
void Visit(Motorcycle& pMotorcycle) {
mAllMotorcycles.push_back(pMotorcycle);
}
std::vector<Motorcycles*> Get() { return mAllMotorcycles; }
};
class Extractor {
public:
// here you extract motorcycles
static std::vector<Motorcycle*> ExtractMotorcycles(std::vector<Vehicle*>& pVehicles) {
MotorcycleExtractingVisitor tMotos;
std::for_each(pVehicles.begin(), pVehicles.end(), tMotos);
return tMotos.Get();
}
// this would be a templatized version, left as exercise to the reader
template<class TExtracted, classtypename TBegItr, typename TEndItr>
static std::vector<TExtracted*> Extract(TBegItr pBeg, TEndItr pEnd) {
ExtractingVisitor<TExtracted> tRequiredVehicles;
std::for_each(pBeg, pEnd, tRequiredVehicles);
return tRequiredVehicles.Get();
}
};
Usage is as follows:
// fixed type version:
std::vector<Motorcycles*> tMotos =
Extractor::Extract(tVehicleVector);
// templatized version (recommended)
std::vector<Motorcycles*> tMotos =
Extractor::Extract<Motorcycles>(
tVehicleVector.begin(),tVehicleVector.end());
Okay, so, the idea is that I have a map of "components", which inherit from componentBase, and are keyed on an ID unique to the most-derived*.
Only, I can't think of a good way to get this to work. I tried it with the constructor, but that doesn't work (Maybe I did it wrong). The problem with any virtual, etc, inheritance tricks are that the user has to impliment them at the bottom, which can be forgotten and makes it less... clean.
*Right phrase? If -> is inheritance; foo is most-derived: foo->foo1->foo2->componentBase
Here's some code showing the problem, and why CRTP can't cut it:
(No, it's not legit code, but I'm trying to get my thoughts down)
#include<map>
class componentBase
{ public: virtual static char idFunction() = 0; };
template <class T>
class component
: public virtual componentBase
{
public:
static char idFunction(){ return reinterpret_cast<char>(&idFunction); }
};
class intermediateDerivations1
: public virtual component<intermediateDerivations1>
{
};
class intermediateDerivations2
: public virtual component<intermediateDerivations2>
{ };
class derived1
: public intermediateDerivations1
{ };
class derived2
: public intermediateDerivations1
{ };
//How the unique ID gets used (more or less)
std::map<char, componentBase*> TheMap;
template<class T>
void addToMap(componentBase * c)
{
TheMap[T::idFunction()] = c;
}
template<class T>
T * getFromMap()
{
return TheMap[T::idFunction()];
}
int main()
{
//In each case, the key needs to be different.
//For these, the CRTP should do it:
getFromMap<intermediateDerivations1>();
getFromMap<intermediateDerivations2>();
//But not for these.
getFromMap<derived1>();
getFromMap<derived2>();
return 0;
}
More or less, I need something that is always there, no matter what the user does, and has a sortable value that's unique to the most-derived class.
Also, I realize this isn't the best-asked question, I'm actually having some unexpected difficultly wrapping my head around it in words, so ask questions if/when you need clarification.
Edit:
Using Beta's phrasing; The class derived2 has an ID number, unique among all classes derived from ComponentBase, and from which no other classes are derived - except that there should be no usage cases in which we're dealing with an instance when we don't know the most-derived type. That is, we should never have to deal with a foo1* that is actually pointing to a ``foo`.
Any time that I need to access this ID, I have type information about the most-derived class; via the templated nature of addComponent, getComponent and removeComponent.
Hmm, to put it another way; I need to "convert" type into a unique number while I know the type, so that I can later distinguish between two things when I don't have the type information.
I don't understand why you are using reinterpret_cast in class component.
As far as having unique IDs, you should have some kind of process to validate that the ID is not used by any derived instance.
On the other hand, each class should implement a static clone or create method. The factory would have a map of . The function pointer points to the specific class' create or clone method. Since the std::map cannot be created as a const static entity during compilation time, I generally use constant static arrays to hold the IDs and function pointers. If the array is small, it is insignificant in performance to a map.
Example:
class Base
{;};
// Declare a synonym for a pointer to the creation function.
typedef Base * (*P_Creation_Function)(unsigned int id);
struct Creation_Entry
{
unsigned int class_id;
P_Creation_Function p_creator;
};
class Child1 : public Base
{
public:
static Base * create(unsigned int id);
};
Creation_Entry creation_table[] =
{
{1, Child1::create},
};
static const unsigned int NUM_CREATORS =
sizeof(creation_table) / sizeof(creation_table[0]);
// Process 1: search table for ID
for (unsigned int i = 0; i < NUM_CREATORS; ++i)
{
if (creation_table[i].class_id == new_id)
{
return (*creation_table[i].p_creator)(new_id);
}
}
// Process 2: Execute each creation function in the table.
// Creation functions will return NULL if the ID is not a match
Base * p_new_object;
for (unsigned int j = 0; j < NUM_CREATORS; ++j)
{
p_new_object = (*creation_table[j].p_creator)(new_id);
if (p_new_object)
{
return p_new_object;
}
}
For small projects, the overhead of a creation function return NULL is not significant compared to other bottlenecks (such as disk i/o). The second process does not require the factory to know the class ID; the class ID remains encapsulated in the class.
I've used both processes and implement them depending on my mood and the project size. :-)
You could make use of the typeid operator.
If you have a ComponentBase* component, then
typeid(*component)
will return a type_info& object that uniquely identifies the class of the object that the component pointer points at. (If component points at a Derived object, then this will return the type_info object that belongs to the Derived class. Note though that typeid(component) would return a type_info& that represents the type ComponentBase*, so dereferencing the pointer is important.)
Then you can use eg. the address of this type_info object, or the result of type_info::name() as the key for your map.