C++ singleton object with derived objects function calls - c++

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.

Related

Variable types from inherited classes

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.

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.

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.

Design question: Holding class metadata for dynamic lookup

I have a couple of base/interface classes each of which has several derived classes. I have a need to store metadata on each derived class that has a lot of overlap, but different values.
I also have a Factory class for creating instances of the derived classes that's implemented as a singleton and has a few macros. For example, you'd:
REGISTER_COMPONENT("MyComponent", MyComponentClass);
// create an instance of each component
BaseComponent *base;
foreach(QString component, ComponentRegister::componentList())
{
base = ComponentRegister::create(component);
// do stuff with base
}
The question is: how and where to store the metadata from a solid design viewpoint.
I could store the data in the ComponentRegister as a QMap structure. When someone registers a component, they could also register its metadata with something like
REGISTER_COMPONENT_METADATA("MyComponent", MyMap);
If the QVariant::isValid() for a particular key, you know the metadata is set and available.
Another way would be static class variables or maybe a static class QMap.
I see advantages and draw backs to both. Most of the metadata are things like "path to QResources for this class" which is not tightly coupled to the business logic of the class itself.
Another issue with the static class variable method comes into play with inheritance. You can't enforce overriding of static class variables like you can with pure virtual functions. So if someone forgets...it could be unclear where in the inheritance tree the values are coming from. If you require access to the metadata through a series of pure virtual "getters" then setting of the MetaData is spread across all implementations of the Base class.
With data held, set, and looked up in the Register if you needed to make changes (like changing the root path for resources), you could do so at a single point...in the class registration calls, probably a header or wrapped in a application Utility function. With static data, you'd have to edit each class declaration.
Open to suggestions and thanks!
If data related to an object isn't specific to a single instance, as the path in your example, my designs usually include a class which manages my collection of objects. That's where I put the meta data.
example:
class zoo { std::vector<animals> zoo_animals; size_t count; }
count is metadata about the animals.