Variable types from inherited classes - c++

If I have a class that inherits from a base class, can I use that base class as a variable type in c++?
class Component {
// Code here
};
class TransformComponent : public Component {
// Code here
};
class Entity {
// Code here
Component *getComponent(Component *searchComponent) {
// Code Here
}
};
as you can see here, I am using the base class "Component" as a return type and a variable type. The problem is that the user may input a "TransformComponent". The only reason I am asking this is because the "TransformComponent" class inherits from the "Component" class and there might be a way to do this?
<Entity>.getComponent(Component &TransformComponent());
The answer I'm looking for is one that works both for the return type, and the variable type.

Absolutely! It's one of the beauties of OOP. Your instanced class of type TransformComponent is both an instance of Component as well as TransformComponent.
If you had some function that returned a type of Component, this could return any class derived from Component as a Component! If you later wanted to refer to it as its sub-class, you might have to check its type and then cast to it, but what you want is absolutely possible, and you're going the right way about it.
In fact, in the example you describe, were you are using Component and the user might pass a TransformComponent, all of the base methods and properties that the Component possesses will be possessed by TransformComponent too. It will look and feel as if it was a Component, with all the benefits of being one.
The only time a problem will arise is if you specifically want to access the features of a TransformComponent, and the user passed a Component. The parent class doesn't know about the sub-class stuff, because it isn't an instance of one, it will throw up errors for you. Sub-classes build upon the base class, so they have all the base-class stuff, plus more. Basically its only an issue when your example is reversed.

Your Entity.getComponent() method suggests that it only cares that the provided argument is a Component ... not any specialization, such as TransformComponent, of that original class.
So, if you find yourself writing logic that actually cares that "this Component might actually be a TransformComponent," then "warning bells should be going off." Create method definitions within the class that are as specific as possible.

Related

c++ base class object to call unknown methods in subclasses

I am facing this problem:
An upstream application defines a class (e.g. box), and a member (say property) with a base class type. I would make a derived class for that member, add new members and methods without updating their application.
Essentially I do box->property = make_shared<myProperty>(). Is there a way to keep the interface of calling the members and methods the same? That is, to access a property using box->property->length or box->property->GetWeight(), rather than dynamic_pointer_cast<myProperty>(box->property)->GetWeight(). The challenge here is they won't update the base property class, and I am not supposed to change box. But we wish to keep the interface the same so our customers won't complain.
Is it possible? If not, how could we do to best keep the main app and my plugin relatively independent while minimize the changes on the customer side? Any suggestions are welcome.
Looks to me like the derived class for that member property violates Liskov's substitution principle.
You mentioned not being able to modify the Box class.
But are you allowed to modify the property base class? I suggest you add your "additional" methods of your derived class to the property base class.
The intent here being that the interface between the base and derived class should be one and the same. So do this only if it makes sense design wise.

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.

C++ singleton object with derived objects function calls

It might be already answered but it has bothered me a lot by giving me headaches so that's why I'm asking for a solution or an explanation.
The thing is that I'm developing a system in which I want to have only one properties(in terms of application) struct or sth accessible from everywhere in my code.
To give you the bigger plan I want to hold all my properties in an class object lets say Properties. So I decided to go with the Singleton on this one.
The point is that I want derived objects with their values and getter-setter methods coming from the base class Properties.
For example I want to have let's say two different objects from two different classes Component1Properties and Component2Properties. Now I want my Properties singleton to create a Components1Properties object and one Component2Properties object so that every-time I'm getting the same instance I'll have the same derived objects.
Now next let's add a static string "property" to each of the derived object and also declare a getter and setter method for this string.
The problem I'm facing is that I want from everywhere in my code to call the derived objects functions and get and set the values inside these objects
Example:
In my .h file:
class Properties
{
public:
static Properties& getInstance()
{
if instance==NULL} instance = new Properties();
return *instance;
}
private:
Properties();
static Properties* instance;
};
class Compoment1Properties : public Properties
{
public:
String property1;
void setProperty1(String value){
property1 = value;
}
String getValue(){
return property1
}
Component1Properties();
~Component1Properties(){};
};
Then in my .cpp file I have
Properties::Properties()
{
Component1Properties component1Properties;
}
I want from everywhere in the code to be able to get or set the values of the Component1Properties with something like:
String value = Properties::getInstance().component1Properties.getValue();
Properties::getInstance().component1Properties.setValue(value);
My questions here are
1. Is this feasible somehow ?
2. Is the architecture correct based on my needs ?
3. I'm I doing anything wrong ?
Thanks for your understanding and sorry if this is something to obvious but actually I'm trying to get familiarised with OOP principles in C++ but things are pretty messed up for me and I'm only getting headaches instead of results.
You can not have it working directly the way you want, simply because if you want to be able to have two objects Component1Properties and Component2Properties, both having Properties as a base class, then you will have at least two copies of Properties class: one in each component properties. This is just how inheritance works, but this clearly breaks your singleton approach.
What you can do is to have Component1Properties hold a reference (or, well, pointer) to a Properties object, and the same for Component2Properties. In this case it will be possible to share Properties object between component properties objects.
You can then have Properties object produce objects for particular components, most probably via some factory pattern, though I would suggest a separate class for this, like PropertiesFactory. It might as well be a singleton or even be contained in in Properties class, though even better might be main PropertiesManager class that is a factory producing global Properties as well as properties for each object.
Another approach that might be feasible if each component properties is just a subset of global properties. In such a case, you can have separate Component{1,2}Properties classes and Properties class that inherits all ComponentXProperties:
class Properties : public Component1Properties, Component2Properties {
};
In this case, you can just cast the global Properties object to any class you need. You may also try tricks with virtual inheritance here if your components have some properties in common, but overall this seems to be too complex and error-prone.
Registry Based Singletons
Use map of Pointers to base class in BASE class for storing objects and class name.
Use protected methods register and unregister in BASE class which accept BASE* and string name for derived class. register and unregister methods insert and remove objects from map, respect. CAREFUL with removal, as removing objects from does not mean invoking destructor!!
Add static lookup method to base class so as to check if object is in map.
3.In DERIVED class, constructors are private. for getInstance you need to do lookup first and if it returns no object, instantiate using private constructor and Register That object with Current derived class name.

Proxy class for polymorphic type, using templates

This is for a "game engine" as a bit of programming practice. All of my GameObjects are component based, where each component adds a functionality to its parent GameObject and all of these components descend from a base Component class which has virtual methods making it polymorphic.
When I read in these gameobject definitions from an XML file some components need to know about others for example a physics component needs to be aware of the transform component for the physics calculations. However if these components aren't present in the XML file then occasionally it throws up nasty null-pointers and endless rabbit hole call stack chasing to find the XML typo I fudged while half asleep.
My solution was to have a node in the XML file as an assertion that a component of this type should exist and possibly throw an exception or another appropriate action if it doesnt.
Eg.
<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>
So I need a way of representing this in C++. The first idea, template classes to change according to what type of component it's the proxy of since this class needs to act like their unproxied component. I've solved that with some operator overloading so long as the class is a template class.
template <class T>
class ComponentRequirement {
public:
T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
return this->component;
}
//Other unrelated functions . . .
private:
T* component;
};
And this is all fine and dandy at compile time because I can just say
ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");
But I need to be able to specify what that template type in place of the will be from a string when I read the XML in. I thought a hashmap could do it but I dont think the type name even "is" anything other than a human readable compiler hint so I couldn't use it as a hashmap value.
Can this be done and how could I go about implementing it? Inserting some string literal into a "black-box of magic" and get something that can be used as a template argument. And if it helps, everything that will be the value of "T" is polymorphic.
Or is there a better solution to my problem. It needs to be able to act as any Component I put into it and it needs to be discernable at runtime.
EDIT 1:
In my components I have a read and write function. If I read the component requirement in there I can make sure the template has the right value because each component is seperate.
I can then evaluate the requirements with a virtual function and a few functions in the gameobject class to check it's a valid configuration. This could solve the problem.
At a first glance I would use the factory pattern for your problem. That way you can create classes to create your objects given a different string without specifying the exact class you need at compile time unlike with normal typed constructors. The analogy I see people use are Virtual Constructors.
http://www.oodesign.com/factory-pattern.html
In essence you would have a map of factories (creator objects).
Define some top level interface for your components, such as IComponent.
Define a factory class for every component you want to generate that has a Create Instance method. I recommend the Create Instance method should be part of an interface like IFactory.
During setup of your program create your map and assign factories to particular keys. ActorCreator["MyComponent"] = new MyComponentFactory();
When you want to create an object read from an XML node you can just call the create instance method on the returned factory for the key. auto myComponent = ActorCreator[readXML]->CreateInstance();
You now have an actor/components whose concrete type has been decided at runtime instead of compile time.

Is it possible to Cast an Object to a not related Class?

Say I have two classes with different names but the exactly same structure. It there a way to cast an object of the one class to one of the other?
This might sound stupid to do but there is a reason why I want to do that. The architecture of my application provides the abstract classes component and storage The ready application will contain several specialized components derived from component and each of them will define its own storage type, derived from storage. During initialization of the application, for each component there will be a storage object of its custom storage type created and passed as pointer to the component.
This way all component stay completely independent which is great for re-usability and testing. But, of course, there is a need to exchange informations between components. To do that with independence in mind, I want to let two components get a storage pointer pointing to the same storage. The pointer by constraint must be of the component specific storage type.
framework code (abstract classes)
class Storage {};
class Component {
public:
void SetStorage(Storage* storage);
private:
Storage* storage;
};
example component
class PhysicsStorage : public Storage;
class PhysicsComponent : public Component;
another component
class CollisionStorage : public Storage; // same structure as PhysicsStorage as both components need the same data like world coordinates and rotations of all forms in the 3d space
class CollisionComponent : public Component;
main application
#include "system.h"
PhysicsStorage Worlddata;
PhysicsComponent Physics;
CollisionComponent Collision;
Physics.SetStorage(&Worlddata);
Collision.SetStorage(&Worlddata); // this points to a PhysicsStorage but that is actually the same like a CollisionStorage which is expected
So I wonder if there is a way of casting the pointer of say PhysicsStorage* to CollisionStorage*. In this case, both are defined in the file of their related component class. And both are derived from abstract Storage.
I only want to do that in the case that both custom storage types have exactly the same structure. Otherwise it would be senseless. I am not so familiar with advances pointer usage so I wonder if there is a way to do that. What I know is that you can cast to a base class, but this isn't what I want here. Using a shared storage type for two components would break independence. Thanks a lot!
This may work, and it may not. I believe this is a case of undefined behavior, and I would avoid doing this in production code.
Consider instead pushing the common fields and methods up into a new class and having ComponentOneStorage and ComponentTwoStorage inherit that class. Then you can pass around pointers/references to the base class instead, which will give you access to the common data without having to cast between incompatible pointer types.