I have several classes (same base class) and only some users allowed to instantiate some. I need to keep allowed classes for a user in a database.
I definitely need some suggestions. Because I think, I should not need to have a list of class names as a string in database and instantiate them in a condition of string comparison. It just does not feel right to me.
Typical scenario is
1. Calling GetAllowedClassesToInstantiate(user) [From Database]
2. Instantiate those classes
Do you have any suggestions?
Regards,
Burak
Make a data structure like this:
class BaseClass;
std::map<std::string, std::function<BaseClass*()> Factories;
and initialize it in the following way:
class One : BaseClass { ... }
void init() {
Factories["One"] = [](){ return new One(); }
}
Basically it will serve as a lookup ClassName -> Constructor.
Keep allowed class names in the database. After you retrieve it, present it to the user and when he chooses an option, look up the proper constructor wrapper function in Factories and use it to instantiate the selected class.
Make sure to keep the database entries up-to-date with the entry keys inFactories.
(I've used some C++11 in the code sample. You can do the same in C++03 with a bit more code, without the lambda expression and std::function, but the idea stays the same.)
Related
I have a class structure like the on below.
class Technology;
class BasicTechnology : public Technology;
class BasicChildTechnology : public BasicTechnology;
class ConcreteChildTechnology1 : public BasicChildTechnology;//concretechildtech1
class ConcreteChildTechnology2 : public BasicChildTechnology;//concretechildtech2
class ConcreteChildTechnology3 : public BasicChildTechnology;//concretechildtech3
...
class ConcreteChildTechnologyN : public BasicChildTechnology;//concretechildtechN
The ConcreteChildTechnologyN/3/2/1 has an isValid(String selector) method, which is as shown below,
public isValid(String selector){
return "concretechildtech1".Equals(selector);
}
Now in the client code is,
Technology tech = getTechnologyObject("concretechildtech1"); //tech becomes an instance of ConcreteChildTechnology1
How should I implement getTechnologyObject() in this case?.
Thought of using the abstract factory pattern, but doubtful of that. or even create a Facade and create the concrete child based on the input argument?
The problem is, only the ConcreteChildTechnology1 knows whether the input string (concretechildtech1) belongs to him or not; via isValid() method.
Again if I start to create N objects every time to check the validity, that will cause and overhead, because 1)the system is running in a very low memory environment like mobile and tablets, 2)the number of instance creation is high, 10-100 per minute.
May be make the isValid() a static inline method and create object based on the reply from child objects?
My understanding is that getTechnologyObject("string") is returning a smart reference/pointer like std::shared_ptr<BasicChildTechnology> based on a string. Inside that function there is a list of these tech objects and only that tech object knows if it is associated with that string.
The first problem is that string. Is it possible to convert it to an enumeration or some more precise data type earlier than now? That alone will make your system more reliable, and faster.
The second problem is the ownership of the match criteria. I imagine when the system was being designed that this felt natural. I would point out that this object does not have a single responsibility. It is both required to do whatever the Tech is, and required to match itself from some serialisation format. It may still make sense to leave the string inside that object (it might be a name) but the matching needs to be elevated out of the object, and into the search function getTechnologyObject("string").
Now regardless of if you have a string/numeric, the tech objects need a function virtual label_t label() (name it as you feel fit) that returns this identifier.
Thirdly your creating a new object each time. That is the factory pattern, but there are two choice on how to implement that. One is giving the power of cloning to each implementation and treat each instance as a prototype. The other is to create a related hierarchy of factories that build those tech objects.
If you go the prototype path also define a virtual std::shared_ptr<BasicChildTechnology> clone() const =0; in the Tech classes. Otherwise create a related TechnologyFactory class tree, or a Factory<T> template. The factory will need something like a label_t label() and a std::shared_ptr<BasicChildTechnology> build().
I'm going to pick prototype here.
Construct the lookup like:
std::map<label_t, std::shared_ptr<BasicChildTechnology>> lookup;
lookup.add(tech1->label(), tech1);
lookup.add(tech2->label(), tech2);
lookup.add(tech3->label(), tech3);
Then:
std::shared_ptr<BasicChildTechnology> getTechnologyObject(const label_t& label)
{
return lookup[label]->clone();
}
And a Factory template here.
Construct the lookup like:
std::map<label_t, Factory<std::shared_ptr<BasicChildTechnology>>> lookup;
lookup.add(factory1->label(), factory1);
lookup.add(factory2->label(), factory2);
lookup.add(factory3->label(), factory3);
Then:
std::shared_ptr<BasicChildTechnology> getTechnologyObject(const label_t& label)
{
return lookup[label]->build();
}
The lookup will execute in log(N) time, for both cases.
What you are trying to do has different solutions based on your exact implementation and what the child types actually do.
If the isValid() method never relies on non-static member variables, isValid() could be made static. Your getTechnologyObject() function could be written as:
Technology* getTechnologyObject(const std::string& _string)
{
if(ConcreteChildTechnology1::isValid(_string)){
return new ConcreteChildTechnology1(/* arguments go here */);
}
/* follow with the rest */
}
As per user4581301's comment you can return a pointer to prevent object slicing.
It seems that your type hierarchy is blowing out in size. To reduce complexity and perhaps make the creation of objects easier, you could explore some form of composition instead of inheritance. This way a factory pattern would make more sense. Perhaps you could create a Technology object based off what is it supposed to do using a decorator pattern.
I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.
Say I have a superclass that, when it initializes, wants to run some code that relies on a whole bunch of class variables that may or may not be overridden by a subclass in its constructor.
What's the accepted, clean way to code that?
I feel like I'm having a brain fart; this should be a standard, beginner usage of inheritance, but I can't figure it out.
e.g. say I have a superclass that represents a vehicle, and when it starts, I want to do a whole bunch of code where it processes, say, the load per axle or something (doesn't matter) but that code uses as inputs a bunch of parameters that exist for all vehicles (and thus exist in the superclass), say weight, length, numwheels, numaxles, maybe even complicated data structures defining how many wheels per axle, etc.).
The various subclasses (sportscar, bigrig, motorcycle), want to set the weight, length, numwheels, numaxles, etc. before the superclass does its processing.
Super::Super() {
Process(var1_,var2_,var3_,var4_, ...);
}
Sub1::Sub1(): Super() {
var1_ = <some math>;
var2_ = <some math>;
...
}
doesn't work because the superclass Process() runs before the vars get set by the subclass. Right?
Super::Super(float var1, WackyDatastructureDef var2, int var3, WackyStruct2 var4, ...),
var1_(var1), var2_(var2), var3_(var3), ............... {
Process(var1_,var2_,var3_,var4_, ...);
}
Sub1::Sub1(): Super(<some math>, <some math>, <some math>, <some math>, ......) {
....
}
looks horrible for obvious reasons. Also, it looks like a pain if I only need to override 2 out of the 20 default variable values.
Super::Super() {}
void Super::Init() {
Process(var1_, var2_, var3_, var4_ ...... );
}
Sub1::Sub1(): Super() {
var1_ = <some math>;
var2_ = <some math>;
...
Init();
}
looks the cleanest but I don't like it... it's weird to have to remember to call Init() at the end of all my subclass constructors. What if another programmer wants to subclass off my superclass and doesn't know my magic rule?
What's the right way to do this?
There are many ways to solve this issue (lack of virtual constructors in C++). Each one has its own benefits and drawbacks. Most common patterns to workaround this limitation:
Pass all required arguments to base class constructor. This can be really annoying if you need more than few parameters. Code will be less and less readable and pretty hard to extend if requirements change. Of course it has a big benefit: it's not a workaround and everyone will understand it.
Change your design (this may be the best thing to do but it may require a lot of work). If you need a lot of parameters then you may pack all arguments in separate class, it'll hold object status. Base class constructor will just accept one parameter of this type and it'll contain its status (or just its initialization data but this is another story). Its benefit is to keep design clear (no workaround like for first solution) but it may involve some complexity if this initialization token will evolve with its own class hierarchy.
Add a public initialization method. Change your Init() method to public, it won't be invoke by derived constructors but by class users. This will allow you to add initialization code in each derived class (and initialization order is then controlled by implementation itself). This method is pretty old school and it requires users will call it but it has one big benefit: it's universally known and it won't astonish anyone. See this post here on SO for a small discussion about them.
Virtual constructor idiom. See this article for a reference. It works as intended and you can make it easier to use with few template methods. IMO biggest disadvantage is that it changes how you manage inheritance and initialization when you create a new derived class. This may be boring and error prone and prolix. Moreover you change how a class is instantiated too and, for me, this is always annoying.
Few notes about second solution (from comments). If you apply this I see at least these options:
Stupid entity (just data, no logic) that holds all required parameters.
Encapsulate object status in a separate object. Object you pass from derived classes is not used and dropped but it'll be part of object.
In both cases you can have or not a parallel hierarchy for parameters (BaseParametersHolder, DerivedParametersHolder and so on). Please note that holder doesn't suffer from same problem of first solution (many arguments) because creation can be delegated to a private function (example is to illustrate concept, code is far to be nice):
class Derived : public Base
{
public:
Derived() : Base(CreateParameters())
{
}
private:
ParameterHolder CreateParameters()
{
ParameterHolder parameters;
parameters.Value = 1;
parameters.AnotherValue = 2;
return parameters;
}
};
What to use? There is not an answer. I'd prefer to be consistent across code (so if you decide to use holders then use them everywhere, do not mix - for example - with v.i. idiom). Just pick proper one each time and try to be consistent.
Pass the relevant information up to the base class constructor.
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).
I am using Qt 4.5 so do C++. I have a class like this
class CClass1
{
private:
struct stModelDetails
{
QString name;
QString code;
..... // only variables and no functions over here
};
QList<stModelDetails> m_ModelDetailsList;
public:
QList<stModelDetails> getModelDetailsList();
...
};
In this I have functions that will populate the m_ModelDetailsList;
I have another class say CClassStructureUsage, where I will call the getModelDetailsList() function. Now my need is that I have to traverse the QList and obtain the name, code from each of the stModelDetails.
Now the problem is even the CClass1's header file is included it is not able to identify the type of stModelDetails in CClassStructureUsage. When I get the structure list by
QList<stModelDetails> ModelList = obj->getModelInformationList();
it says stModelDetails : undeclared identifier.
How I can able to fetch the values from the structure? Am I doing anything wrong over here?
Since struct stModelDetails is private, it is not visible from outside the class. You should declare it in the public section of your class instead:
class CClass1
{
private:
QList<stModelDetails> m_ModelDetailsList;
public:
struct stModelDetails
{
QString name;
QString code;
..... // only variables and no functions over here
};
QList<stModelDetails> getModelDetailsList();
...
};
You need to use the fully qualified name CClass1::stModelDetails. Now it will tell you it is private :)
You've already gotten a couple of suggestions for how to attack your problem directly. I, however, would recommend stepping back for a moment to consider what you're trying to accomplish here. First of all, you've said you only really want the name member of each stModelDetails item. Based on that, I'd start by changing the function to return only that:
QList<QString> GetModelDetailNames();
or, quite possibly:
QVector<QString> GetModelDetailNames();
The former has a couple of good points. First, it reduces the amount of data you need to copy. Second, it keeps client code from having to know more implementation details of CClass1. The latter retains those advantages, and adds a few of its own, primarily avoiding the overhead of a linked list in a situation where you haven't pointed to any reason you'd want to use a linked list (and such reasons are really fairly unusual).
The alternative to that is to figure out why outside code needs access to that much of CClass1's internal data, and whether it doesn't make sense for CClass1 to provide that service directly instead of outside code needing to access its data.
The problem is that you declared stModelDetails as a private class. Putting it in the public section should fix your problem.
There are two problems:
1. Already mentioned is that you need to move stModelDetails to the public section of your class.
2. Because it is nested, the proper name for it outside of the class is CClass1::stModelDetails.
If you really need access to it from the outside, you may want to consider whether it should be a member of CClass1 or if it should be a stand alone class or struct. I usually only use nested classes/structs when they are an implementation detail of my class.