Store any value and a value of a specific range of classes - c++

I have a class that looks something like this:
class container{
private:
std::vector<physical_component> physical;
std::vector<storage_component> storage;
--some other stuff not relevant--
public:
--constructors, getters setters, methods to add to the vectors etc--
}
Now I am struggeling with making the physical_component and storage_component classes since I dont know a proper datatype to handle this sort of thing.
Physical_component should be able to:
Store a set amount of types, and fully retaining a type (something I can cast to is good enough)
Should store the objects in a way that makes them individual from the ones passed (and therefore secure from changes to the orignial class)
I remember something like that excisting in c alongside enum but I dont know the name. Also c++ probably has a better way for that.
Storage_component is supposed to:
Store any type
(optional) remember the original type
I have no idea how to achieve this properly. I saw std::any but it seems to be rather new therefore I dont know if its a good way to go about this. Also I cant make storage_component a template because I cant store it in a vector then
What is the (proper) way to implement these classes?

Store a set amount of types, and fully retaining a type
You probably want std::variant<Ts...> (or boost::variant<Ts...>). It stores one of Ts... at a particular point in time.
Store any type
If all the types share the same interface, use a traditional virtual + std::unique_ptr polymorphism approach. Otherwise std::any is the right choice here.

Related

C++ Template Classes, Inheritance and Writing Generic Code for Graph Drawing

Background Info
I am writing a graph-drawing program. I have encountered a problem with templates and inheritance, and I do not know how to proceed. I do not know how I should design my code to enable me to do what I am trying to do. (Explanation below.)
Target
I have a template class, which represents "data". It looks something like the following:
template<typename T>
class GraphData
{
std::vector<T> data_x;
std::vector<T> data_y; // x and y should be held in separate vectors
}
This class is part of an inheritance hierarchy involving several classes.
The hierarchy looks something like this... (Sorry this is from my notes, awful diagram.)
Explanation
There is a base class. No real reason to have it right now, but I anticipate using it later.
Base_Legend adds functionality for legend drawing. New members added include a std::string, and Get/Set functions.
Base_Drawable adds a pure abstract = 0 member. void Draw(...). This is to force overloading in all inherited objects which are drawable.
GraphData_Generic adds functionality for adding/removing data points to a set of vectors. These are pure abstract methods, and must be overridden by any data classes which inherit.
GraphData and HistogramData are 2 data types which have implementations of the functions from GraphData_Generic. (No implementation of Draw().)
GraphData_GenericDrawable doesn't do anything. It is to be used as a base class pointer, so that a vector of these objects can be used as data (add/remove data points) and can be draw (using void Draw()). This class also can be used to call the Get()/Set() methods for the std::string to be used in the legend.
Finally, at the bottom are GraphData_Drawable and HistogramData_Drawable which overload the void Draw() function. This code specifies exactly how the data should be drawn, depending on whether we have a Histogram or general set of data points.
Problem
Currently, I am using template types. The type of data for the datapoints / histogram bin values is specified by using a template.
For example, one can have a HistogramData<double, HistogramData_Drawable<double>, HistogramData_Drawable<int>, etc... Similarly, one can have GraphData<double>, GraphData<float>, GraphData_Drawable`, etc...
So hopefully it should be fairly obvious what's going on here without me uploading my ~ 10000 lines of code...
Right, so, in addition I have some class Graph, which contains a std::vector<GraphData_Generic_Drawable*>, hence the use of the base class pointer, as suggested above.
BUT! One has to decide what type of data should be used as the underlying type. I MUST choose either std::vector<GraphData_Generic_Drawable<double>*> or std::vector<GraphData_Generic_Drawable<float>*>.
This isn't useful, for obvious reasons! (I could choose double and force the user to convert all values manually, but that's just an easy way out which creates more work later on.)
A (very) ugly solution would be to have a std::vector<> for each possible type... int long unsigned long long double float unsigned char... etc...
Obviously this is going to be hideous and essentially repeat loads of code..
So, I intend to implement an AddData method which adds data to that vector, and I also currently have the following method:
// In class Graph
void DrawAll()
{
for(std::vector<GraphData_Drawable*>::iterator it = m_data.begin(); it != m_data.end(); ++ it)
(*iterator)->Draw(arguments);
} // Draw function takes arguments including a canvas to draw to, but this isn't directly relevant to the question
Which iterates over the vector and calls Draw for each set of data in there.
How to fix it?
My current thoughts are something along the lines of; I need to implement some sort of interface for an underlying data class, which retrieves values independent of the underlying type. But this is only a very vague initial idea and I'm not really sure how I would go about implementing this, hence the question... I'm not sure this is even what I should be doing...
If this isn't clear ask me a question and I'll update this with more details.

Selecting the right strategy based on two object types

I'm not sure how to name this problem, so I'm going to try to explain as good as I can.
I want to be able to switch strategies depending on the types of two different objects. To make this work, I am thinking of flagging the objects with an enum type, and having a 'registry' (arrayish) of these strategies. Ideally, the correct strategy would be accessed with some simple operation like a bitwise operator between the two types.
This pseudocode may make what I'm trying to explain easier to understand:
enum Type { A, B, C }
struct Object {
Type type;
}
class ActionRunner {
vector<Strategy> strategies;
void registerStrategy(type1, type2, strategy) {
strategies[type1 operator type2] = strategy;
}
void runStrategyFor(type1, type2) {
strategies[type1 operator type2].execute();
}
}
This would be easy to solve using a map, but I'd like to use an array or vector because a map seems like an overkill for a problem like this and using an array is probably much faster.
So the problem is I don't know what operator I might be able to use to select the 'position' of the right strategy. I've been thinking of a few combinations but it seems all of them end up causing collisions with the different combinations at some point.
Does anyone have any clues/advice on what I may be able to use for this?
PS: I know premature optimization is bad, but I'm just trying to figure out if this problem can be solved in a simple way.
------- EDIT ------------------------------------------------
In light of the answers, I've been giving the problem some extra thought and I've come to the conclusion what I intended with this question isn't possible the way I'd like it. I'm going to try to re-state the problem I'm trying to solve now using this question.
I'd like to have a class structure in which there's objects of certain type 'BaseClass' and a 'processor' object that takes two objects derived from 'BaseClass' and runs the right strategy for those. Something like this:
class Processor {
void run (DerivedA a, DerivedB b);
}
class BaseClass {}
class DerivedA: public BaseClass {}
class DerivedB: public BaseClass {}
BaseClass a = new DerivedA;
BaseClass b = new DerivedB;
processor.run(a, b)
According to what I understand, this would not work as I'd expect if what is passed as parameters to 'run' are references, which is what I'd rather do. Is there any way to do this without way-too-complicated code? (tripple dispatch!?)
I have in mind something like the double dispatch combined with an slave (processor) object that I think would work, but that seems awfully complex and probably a pain to maintain and extend.
Thanks!
The second sentence of your question rang a bell for me:
I want to be able to switch strategies depending on the types of two different objects.
This sounds like you want to perform a double dispatch. See the question (in particular, the answers to the question ;-)) at Double dispatch/multimethods in C++ for how to implement this in C++.
That's a classic example for using map instead of array. Array is actually a private case of map with key defined as an integer. In your case the key is a tuple so a simple array won't do and you'll end up with collisions (even if you're lucky for your specific input, your code will be extremely non-robust).
You can have an intermediate solution, between simple array and map: 2D array, with your 2 types serving as indices to rows and columns..

Retrieving values of collection from multiple classes, what's the correct way?

Before anything, thanks for reading!
I'm developing an application in C++ and I want an advice about a design issue. Let me explain:
The main class of my application has some collections, but other classes eventually need to get a value from one of those collections. Something like this:
class MainClass {
private:
// Collections are internally implemented as QHash
Collection<Type1> col1;
Collection<Type2> col2;
};
class RosterUnit {
public:
RosterUnit() {
/* This method needs to get a specific value from col1 and
initialize this class with that data */
}
};
class ObjectAction {
public:
virtual void doAction() = 0;
};
class Action1 : public ObjectAction {
public:
void doAction() {
// This needs a specific value from col2
}
};
class Action2 : public ObjectAction {
public:
void doAction() {
// This needs a specific value from col1
}
};
My first approach was passing the whole collection as parameter when needed, but it is not so good for ObjectAction subclasses, because I would have to pass the two collections and if I later create another subclass of ObjectAction and it needs to get an element from other collection (suppose col3), I would have to modify the doAction() signature of every ObjectAction subclass, and I think that is not too flexible. Also, suppose I have a Dialog and want to create a RosterUnit from there. I would have to pass the collection to the dialog just to create the RosterUnit.
Next I decided to use static variables in RosterUnit and ObjectAction that pointed to the collections, but I'm not very happy with that solution. I think it is not flexible enough.
I have been reading about design patterns and I first thought a Singleton with get functions could be a good choice, but after some more investigation I think it isn't a proper design for my case. It would be easier and more or less the same if I use global variables, which don't seem to be the right way.
So, could you give some advices, please?
Thank you very much!
As mentioned previously, Iterators are good for abstracting away the details of the Collection. But going this route implies that the objects that use the Iterators will need to know about what's inside the Collection. Meaning they will need to know how to decide which object in the Collection they need, thus increasing the coupling. (more details below in the Factory paragraph) This is something you need to consider.
Another approach would be to create accessor methods on the MainClass that take some sort of key and return an object from the Collection (findObject(key)). Internally the MainClass methods would search through the container(s) and return the appropriate object. To use this approach, you will however need access to the MainClass, either by dependancy injection as mentioned before, or possibly making it a Singleton (not recomended in this scenario, though).
With the info provided so far, it may even be better for your ObjectAction Factory to have a reference to the MainClass, and as a part of the ObjectAction creation logic, call the appropriate MainClass accessor and pass the result into the ObjectAction, thus decoupling the ObjectAction Objects from the MainClass.
You probably want to use iterators, they exist exactly for the purpose of abstracting away sequences from specific containers.
If your issue is how to pass the iterators to the code that needs them in the first place, do not give in to the temptation to use globals. It may look more convoluted if you have to pass parameters in, but your code is that much more decoupled for it. "Dependency Injection" is a good keyword if you want to read more about this topic.
I would also advise you to check out std::function or boost::function instead of inheriting from ObjectAction. Functional style is getting more common in modern C++, as opposed to how it's usually done in languages like Java.
There's not enough information here of what you are trying to do. You make it sound like 'at some point in the future, this statically created action needs this data that was left behind.' How does that make any sense? I would say either construct the actions with the data, as you would for instance with a Future or Callable), or have the command ask for the next piece of data, in which case you are just implementing a Work queue.
Sounds like you are trying to do something like a thread pool. If these actions are in any way related, then you should have then in some composing object, implementing something like the Template Method pattern, e.g. execute() is abstract and calls a few other methods in a fixed sequence and that cannot be overridden, the other methods must be (protocol enforcement).

C++ should all member variable use accessors and mutator

I have about 15~20 member variables which needs to be accessed, I was wondering
if it would be good just to let them be public instead of giving every one of them
get/set functions.
The code would be something like
class A { // a singleton class
public:
static A* get();
B x, y, z;
// ... a lot of other object that should only have one copy
// and doesn't change often
private:
A();
virtual ~A();
static A* a;
};
I have also thought about putting the variables into an array, but I don't
know the best way to do a lookup table, would it be better to put them in an array?
EDIT:
Is there a better way than Singleton class to put them in a collection
The C++ world isn't quite as hung up on "everything must be hidden behind accessors/mutators/whatever-they-decide-to-call-them-todays" as some OO-supporting languages.
With that said, it's a bit hard to say what the best approach is, given your limited description.
If your class is simply a 'bag of data' for some other process, than using a struct instead of a class (the only difference is that all members default to public) can be appropriate.
If the class actually does something, however, you might find it more appropriate to group your get/set routines together by function/aspect or interface.
As I mentioned, it's a bit hard to tell without more information.
EDIT: Singleton classes are not smelly code in and of themselves, but you do need to be a bit careful with them. If a singleton is taking care of preference data or something similar, it only makes sense to make individual accessors for each data element.
If, on the other hand, you're storing generic input data in a singleton, it might be time to rethink the design.
You could place them in a POD structure and provide access to an object of that type :
struct VariablesHolder
{
int a;
float b;
char c[20];
};
class A
{
public:
A() : vh()
{
}
VariablesHolder& Access()
{
return vh;
}
const VariablesHolder& Get() const
{
return vh;
}
private:
VariablesHolder vh;
};
No that wouldn't be good. Image you want to change the way they are accessed in the future. For example remove one member variable and let the get/set functions compute its value.
It really depends on why you want to give access to them, how likely they are to change, how much code uses them, how problematic having to rewrite or recompile that code is, how fast access needs to be, whether you need/want virtual access, what's more convenient and intuitive in the using code etc.. Wanting to give access to so many things may be a sign of poor design, or it may be 100% appropriate. Using get/set functions has much more potential benefit for volatile (unstable / possibly subject to frequent tweaks) low-level code that could be used by a large number of client apps.
Given your edit, an array makes sense if your client is likely to want to access the values in a loop, or a numeric index is inherently meaningful. For example, if they're chronologically ordered data samples, an index sounds good. Summarily, arrays make it easier to provide algorithms to work with any or all of the indices - you have to consider whether that's useful to your clients; if not, try to avoid it as it may make it easier to mistakenly access the wrong values, particularly if say two people branch some code, add an extra value at the end, then try to merge their changes. Sometimes it makes sense to provide arrays and named access, or an enum with meaningful names for indices.
This is a horrible design choice, as it allows any component to modify any of these variables. Furthermore, since access to these variables is done directly, you have no way to impose any invariant on the values, and if suddenly you decide to multithread your program, you won't have a single set of functions that need to be mutex-protected, but rather you will have to go off and find every single use of every single data member and individually lock those usages. In general, one should:
Not use singletons or global variables; they introduce subtle, implicit dependencies between components that allow seemingly independent components to interfere with each other.
Make variables const wherever possible and provide setters only where absolutely required.
Never make variables public (unless you are creating a POD struct, and even then, it is best to create POD structs only as an internal implementation detail and not expose them in the API).
Also, you mentioned that you need to use an array. You can use vector<B> or vector<B*> to create a dynamically-sized array of objects of type B or type B*. Rather than using A::getA() to access your singleton instance; it would be better to have functions that need type A to take a parameter of type const A&. This will make the dependency explicit, and it will also limit which functions can modify the members of that class (pass A* or A& to functions that need to mutate it).
As a convention, if you want a data structure to hold several public fields (plain old data), I would suggest using a struct (and use in tandem with other classes -- builder, flyweight, memento, and other design patterns).
Classes generally mean that you're defining an encapsulated data type, so the OOP rule is to hide data members.
In terms of efficiency, modern compilers optimize away calls to accessors/mutators, so the impact on performance would be non-existent.
In terms of extensibility, methods are definitely a win because derived classes would be able to override these (if virtual). Another benefit is that logic to check/observe/notify data can be added if data is accessed via member functions.
Public members in a base class is generally a difficult to keep track of.

How to allow your data structure to take in objects of any class - C++

How do I do that? Like you know in Java, you can use an ArrayList and it will take any object as long as you cast it down to whatever it is when you're retrieving the object.
Even better, you can specify what class of objects that ArrayList would store by doing...
new ArrayList()< whateverObject >
I've implemented a linked list data structure in C++ and I'd like to know how I can allow it to do this...
At the moment, I'm just using...
typedef whateverObject ItemType
at the start of my header file for my linked list and then manipulating "ItemType" throughout the implementation of the linked list. So every time I want to change the type, e.g. instead of using the list for storing strings, I want to store an int, I'll have to change the typedef in my linked list's header but I want to be able to simply use it for any object so...
How?!
Thanks.
Templates are the answer to your question.
Define your linked list as follows :
template<typename ItemType>
class ArrayList
{
// What's inside your class definition does not need to be changed
// Include your method definitions here and you'll be fine
};
The type to use is then ArrayList<WhateverObject>.
Use templates. It's a lot to explain so I'll just give you a link where it's explained much better than I'll ever be able to do here: C++ FAQ - Templates.
While you're at it, if you have the time, I suggest you read the whole FAQ, it's really a great resource!
If I have understood well what you ask, templates is what you want.
Take a look here:
http://www.cplusplus.com/doc/tutorial/templates/
In java you can do so, because all classes are inherited from one base class Object. In C++ you do not have it. The reason is that Object base class impose overhead for all objects, while C++ do not like any unnecessary overhead.
If you want to store any object - you can store "void *" data type. The question remained - what you will be able to do with objects, without the knowledge of the type? If you do know - you can cast to the needed type and use it. The practice described above is not safe, and templates are better in most cases.