How to: derived member in derived class with derived class specific methods - c++

I am using C++ under Ubuntu 11.10 and the latest version of NetBeans. Let's say I have the
following code:
class Node {}
class DerivedNode : public Node {}
class Graph {
vector<Node*> nodes;
}
class DerivedGraph : public Graph { }
At the moment I'm storing DerivedNodes in the DerivedGraph class like this for example:
nodes.push_back(new DerivedNode());
When I need to use specific methods that only apply to DerivedNodes and DerivedGraphs
I am forced to use a dynamic_cast on my Node pointers first.
I would like to be able to have specific methods in DerivedGraph which apply only to DerivedNodes
and avoid the need of casting pointers. I do not mind having to redesign my classes if the end
result is better than what I have.
I am sure there must be a clean and simple method to achieve the same thing I'm trying to do.
Maybe something with specialized templates? Any thoughts on the matter would be greatly
appreciated. I'll also provide any additional information required in the case I haven't been too
clear.
EDIT: I don't have two copies. I wanted to put emphasis on how it looks. I apologize for the presentation. What I want to obtain is:
class DerivedGraph: public Graph {
vector<DerivedNode*> nodes;
}

Are you sure that your interface in Node is appropriate? Sometimes when you find yourself needing to downcast (especially in a case like this where base pointers are stored in a container) that may be a signal that your abstract interface doesn't cover all your needs properly. Often something like the Template Method pattern solves all your needs without needing a downcast at all.
However, assuming that your inheritance model really need work in such a way, what you probably want to do is have virtual methods that get overridden in DerivedGraph for adding and getting nodes. You will have to verify the node type and downcast it in this case.
One final approach is to have two separate containers, one in the parent that contains all nodes that aren't DerivedNode and then another container in DerivedGraph that contains all the DerivedNode. Then you use overridden functions again to determine which container to access depending on your API needs.

Start by not duplicating your data member in the derived class.
Then add virtual member functions that you use to add data to your container. That way you can create instances of derived types in the derived class and add them to the container.
Finally, when you override the virtual function that returns a reference to data in the derived class, use covariant return types.

Related

Determine real type of base pointer in a big hierarchy without dynamic_cast

Suppose, that I have an abstract base State class and at least two derived classes AnimalState and PlantState(also abstract). Also, I have many derived classes from AnimalState and PlantState.
class State{} // abstract
class AnimalState: public State{} // abstract
class PlantState: public State{} // abstract
//maybe few more of such classes here
class AnimalStateSpecific1: public AnimalState{}
class AnimalStateSpecific2: public AnimalState{}
... //many of them
class PlantStateSpecific1: public PlantState{}
class PlantStateSpecific2: public PlantState{}
... //many of them
Now suppose, that I use them in some kind of method that operates on base State pointers. Those pointers are replaced over time with other pointers to different class from the State hierarchy. It happens by some rule, specifically within the predefined state graph.
Now to the question part. In order to determine the next state, I need to know the previous one. But since I have only base State pointers, I can not efficiently tell what type of state I have, without doing dynamic_cast to every derived class in the hierarchy that is not good. I can have some enum with all kinds of states that I have, but I do not really like that because I do not want to mix information from two hierarchy branches, as it is really different. Also, I do not like different enums for every branch in the hierarchy such as AnimalStateEnum, PlantStateEnum etc.
What is the best solution for this problem? Maybe my design is not good from the start? I want to keep it as generic as possible and work only with base class objects, if possible.
Now to the question part. In order to determine the next state, I need to know the previous one.
Simplest solution based on limited information we have - object, which knows it's own state creates next state object:
class State{
public:
...
virtual std::unique_ptr<State> transform( some data ) = 0;
};
then you implement it in each derived from State class which can change it's state and knows where it can move to. What data you need to pass is not a simple question - it depends on your task and may have various options, but you need to define something that can be used by all derived classes, as signature is defined on the base class and shared on all derived ones.
What is the best solution for this problem? Maybe my design is not good from the start?
This question is not trivial and only can be answered having pretty deep knowledge on your task. If you are unsure - implement a prototype and check if solution fits your problem well. Unfortunately the only way to learn how to create a good design is your own experience (except trivial cases of course).
You could simply have a virtual method next() inside the state class hierarchy,
and then do something similar to the following example:
State *globalState = nullptr;
void foo(State *s)
{
globalState = s->next();
}
Where each derived class will implement next() to its own meaning:
PlantStateSpecific1 *AnimalStateSpecific1::next(){ return new PlantStateSpecific1; }
AnimalStateSpecific1 *PlantStateSpecific1::next(){ return new AnimalStateSpecific1; }
This is more OOP than having an enum / integer descriptor of the derived class.
What you can have is an integer inside the base state class that every class below it will set in its constructor. Then you can either use a sereis of constants, a list of possible states with the id corresponding to the state type index, or use an enumerator.
The id is more flexible as you can create state types with relative ease and add handling to them without too much difficulty, aswell as if you want to create a new state from the id type.
Just one of the ways iv done this before, but there are probably many others.

Casting to subclass from a collection of base pointers

I need to model a service retriever class to retrieve various services.
Suppose you have a collection of Services, each Service retrievable with a unique string key
(eg. : Services.getService("render"); should retrieve the service indexed as "render").
Now, Service is the base class of various *Service inherited classes, like RenderService, InputService et al. , each one with their different methods.
Now, this could be simply modeled with a std::unordered_map<std::string, Service*>, but it returns a pointer to the base class and not to the derived class (so far, it's pretty obvious). This means I can't automatically call the requested service's methods without doing an explicit cast, I must write something like: ((RenderService*)Services.at("render"))->callRenderServiceMethod();.
This is pretty ugly and redundant, because the at method key is logically linked to RenderService.
I could skirt around the problem by declaring:
#define CALL_RENDER ((RenderService*)Services.at("render"))
and using it as
CALL_RENDER->callRenderServiceMethod();
Although it looks like a clever "hack", it's not the right way to solve this problem.
I've also tried to do something like getService<RenderService>("render"); but it doesnt work well and the redundancy problem is still there.
In the end, I'm doing this because I'd like to avoid this :
class Services
{
public:
RenderService& getRenderService();
AudioService& getAudioService();
AnotherInheritedService& getAnotherInheritedService();
private:
RenderService _renderService;
AudioService _audioService;
AnotherInheritedService _anotherInheritedService;
};
What kind of approach should I use for this kind of problem?
From what I understand from the problem, you need the functions to be declared as virtual functions.
Declaring a function virtual in the base class definition and implementing that function in each derived class will allow the appropriate class' function to be called based on the type of class pointer.
Now, I don't understand why you only have pointers to the base class only. Logically, the pointers you're getting from unordered_map are being returned should be actually derived class pointers but only being "upcasted" to a base class pointer.

C++ inheritance pattern

I am after your opinion on how best to implement an inheritance pattern in C++. I have two base classes, say
class fooBase{
protected:
barBase* b;
};
class barBase{};
where fooBase has a barBase. I intend to put these classes in a library, so that wherever I have a fooBase it can use its barBase member.
I now intend to create a specialisation of these in a specific program
class fooSpec : public fooBase{};
class barSpec : public barBase{};
Now I want fooSpec::b to point to a barSpec instead of a barBase. I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
Is there another way that this is often acheived?
Cheers.
Create a method in your specclass to cast the b into the special version.
That way instead of casting it all the time, it looks like a getter.
On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.
You may consider the template solution:
template <class T>
class fooBase{
protected:
T* b;
};
and then use it as
class fooSpec : public fooBase<barSpec>{};
while ordinarily, the base would be used as fooBase<barBase>.
Is this what you want?
Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.
Now I want fooSpec::b to point to a barSpec instead of a barBase.
There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.
I know that I can just initialise b with a new barSpec, but this would
require me to cast the pointer to a barSpec whenever I wanted to use
specific functions in the specialisation wouldn't it?
Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.
Is there another way that this is often acheived?
Not that I'm aware of.
this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
That depends on whether the method you are trying to invoke is defined in the superclass and whether it is virtual.
You need to cast the pointer before invoking a method if one of the following is true...
The method belongs to the subclass only
The superclass has an implementation of the method and the subclass's implementation does not override the implementation in the superclass. This amounts to a question of whether the function is a virtual function.
Avoid data members in non-leaf classes, use pure virtual getters instead. If you follow this simple rule, your problem solves itself automatically.
This also makes most non-leaf classes automatically abstract, which may seem like an undue burden at first, but you get used to it and eventually realize it's a Good Thing.
Like most rules, this one is not absolute and needs to be broken now and then, but in general it's a good rule to follow. Give it a try.
If it looks too extreme, you may try one of the design patterns that deal with dual hierarchies such as Stairway to Heaven.

Class design to avoid need for list of base classes

I'm currently in the design phase of a class library and stumbled up on a question similar to "Managing diverse classes with a central manager without RTTI" or "pattern to avoid dynamic_cast".
Imagine there is a class hierarchy with a base class Base and two classes DerivedA and DerivedB that are subclasses of Base. Somewhere in my library there will be a class that needs to hold lists of objects of both types DerivedA and DerivedB. Further suppose that this class will need to perform actions on both types depending on the type. Obviously I will use virtual functions here to implement this behavior. But what if I will need the managing class to give me all objects of type DerivedA?
Is this an indicator of a bad class design because I have the need to perform actions only on a subset of the class hierarchy?
Or does it just mean that my managing class should not use a list of Base but two lists - one for DerivedA and one for DerivedB? So in case I need to perform an action on both types I would have to iterate over two lists. In my case the probability that there will be a need to add new subclasses to the hierarchy is quite low and the current number is around 3 or 4 subclasses.
But what if I will need the managing class to give me all objects of
type DerivedA?
Is this an indicator of a bad class design because I have the need to
perform actions only on a subset of the class hierarchy?
More likely yes than no. If you often need to do this, then it makes sense to question whether the hierarchy makes sense. In that case, you should separate this into two unrelated lists.
Another possible approach is to also handle it through virtual methods, where e.g. DeriveB will have a no-op implementation for methods which don't affect that. It is hard to tell without knowing more information.
It certainly is a sign of bad design if you store (pointers to) objects together that have to be handled differently.
You could however just implement this differing behaviour as an empty function in the base class or use the visitor pattern.
You can do it in several ways.
Try to dynamic_cast to specific class (this is a bruteforce solution, but I'd use it only for interfaces, using it for classes is a kind of code smell. It'll work though.)
Do something like:
class BaseRequest {};
class DerivedASupportedRequest : public BaseRequest {};
Then modify your classes to support the method:
// (...)
void ProcessRequest(const BaseRequest & request);
Create a virtual method bool TryDoSth() in a base class; DerivedB will always return false, while DerivedA will implement the required functionality.
Alternative to above: Create method Supports(Action action), where Action is an enum defining possible actions or groups of actions; in such case calling DoSth() on class, which does not support given feature should result in thrown exception.
Base class may have a method ActionXController * GetControllerForX(); DerivedA will return the actual controller, DerivedB will return nullptr.
Similarly, base class can provide method: BaseController * GetController(Action a)
You asked, if it is a bad design. I believe, that it depends on how much functionality is common and how much is different. If you have 100 common methods and only one different, it would be weird to hold these data in separate lists. However, if count of different methods is noticeable, consider changing design of your application. This may be a general rule, but there are also exceptions. It's hard to tell without knowing the context.

Calling a Child class' method when processing a list of Parent class objects

This question seems like it might be somewhat common, but I didn't find anything when scowering StackOverflow or the interwebs.
I came across a method in a C++ class that takes a list of (for example) Parent objects. For this example, assume that there are two classes that derive from Parent: Child1 and Child2.
For each object in the list, the method checks if the object is of type Child2 (via a IsOfType() method that each class implements), and if so, it calls a method that is only provided by the Child2 class.
Is this an issue in that the list-processing method cannot treat each object the same? I've seen this done in other places as well, so it seems it might be a common practice to some degree.
One option might be to declare the Child2 method in the Parent class so that all Parent objects implement it. However, in this case, only the Child2 class would actually implement any behavior when overriding the method.
Your thoughts? Thanks in advance!
I think the following is a better solution for this problem.
class Parent {
public:
virtual int doSomething() {}
};
class Child1 : public Parent {
};
class Child2 : public Parent {
public:
virtual int doSomething();
Now you just omit the IsOfType call altogether and call doSomething on all of the pointers passed to you.
The only good reason I can think of as to why you'd have an IsOfType function is if you don't have control over the Parent class and can't modify it to add the doSomething method.
You could declare the new method in an interface that only Child2 implements. You could then use dynamic_cast<ISomeOtherInterface> to see if the object supports the extended feature. This cast will result in a null pointer for objects that don't support the additional interface.
This would allow you to create other objects that implement this feature, without requiring your list processing to know about each specific object type.
If your IsOfType() test passes, you can cast the (pointer to the) parent object to a Child2 object and access its specific member functions.
EDIT:
This depends on your design and on how strict you ensure the IsOfType() implementation will give correct answers (i.e. it also works when you add new subclasses in a week). It might be safer to make use of the builtin Typeid instead.
Implementing every possible method any child would ever have in the parent would be difficult, so upcasting is ok when the method is really semantically specific to the Child2 class.
You might find the Visitor Pattern useful in this instance. This will allow the objects themselves (child1, child2 etc) to call you back with their static type and take appropriate action.