The idea is for the users to create a new class and inherit only the base class and few special classes whose special functions they want.
class Base {
Data data;
public:
void init(Data d) data(d) {}
// other basic functions
}
class SpecialX: public Base {
public:
Result specialX() {
Result r = compute(data); // uses Base::data to compute some result
return r;
}
}
class SpecialY: public Base {
public:
Result specialY() {
Result r = compute(data); // uses Base::data to compute some result
return r;
}
}
If user wants only init and specialX functions, they could do something like -
class My: public Base, public SpecialX {} // user doesn't need specialY function, so they do not inherit it
My m;
m.init(someData);
m.specialX(); // returns the result by computing specialX
But this throws the ambiguity error due to the Diamond problem in C++.
How do I structure my classes so that I can create as many special classes as I want, and let users inherit the ones that they need?
Related
I want to know the type of my class at compilation and i want to know if my idea is considered bad programming or if its actually viable. May correct me if there is a better way to realize this.
class Base {
int type = 0;
}
class Derivative : public Base{
Derivative(){
type = 1;
SomeObject1 o;
SomeAnotherObject o1;
}
}
class Derivative2 : public Base{
Derivative2(){
type = 2;
RandomObject test;
AnotherObject v;
}
}
Some method that gets myBaseClass as Base:
if(myBaseClass.type == 1){
Derivative d = static_cast<Derivative>(myBaseClass);
d.o;
d.o1;
}
if(myBaseClass.type == 2){
Derivative2 d = static_cast<Derivative2>(myBaseClass);
d.test;
d.v;
}
In my opinion it would be unusual to write virtual methods for all different Objects
Is saving the type in the base class considered bad programming
Definitely, yes!
Using a polymorphic virtual design you don't need to have that extra information stored into the base class. The compiler already does that for you:
class Base {
protected:
virtual ~Base() {} // <<<<<<<<<<<<<
}; // Note the ;!
class Derivative : public Base{
};
class Derivative2 : public Base{
};
You can always detect the real class type from a Base pointer or reference with a dynamic_cast then:
Base* pd1 = new Derivative();
Base* pd2 = new Derivative2();
if(dynamic_cast<Derivative>(pd1)) { // Yields true
}
if(dynamic_cast<Derivative>(pd2)) { // Yields false
}
Though if you need to know that, that's a serious indicator of a bad design.
You should rather introduce some interfaces in form of pure virtual function definitions:
class Base {
protected:
virtual ~Base() {}
public:
virtual void DoSomething() = 0;
};
class Derivative : public Base{
public:
void DoSomething() override {
// provide an implementation specific for Derivative
}
};
class Derivative2 : public Base{
public:
void DoSomething() override {
// provide an implementation specific for Derivative2
}
};
That allows you to call DoSomething() without knowing the specific type that implements that function:
Base* pd1 = new Derivative();
Base* pd2 = new Derivative2();
pd1->DoSomething(); // calls Derivative specific implementation
pd2->DoSomething(); // calls Derivative2 specific implementation
To make safe and efficient use of the static_cast use the CRTP instead:
template<typename Derived>
class Base {
public:
void DoSomething() {
static_cast<Derived*>(this)->DoSomething();
}
};
class Derivative : public Base<Derivative> {
};
class Derivative2 : public Base<Derivative2> {
};
Here's the (ugly) approach I used a few years back when hacking-together a pdf writer. It appears to solve exactly the same problem that you have.
pdfArray::pdfArray(const pdfArray &src)
{
vecObjPtrIter iter;
pdfObj *ptr;
mArray = new vecObjPtr;
for (iter=src.mArray->begin(); iter!=src.mArray->end(); iter++)
{
ptr = *iter;
if (typeid(*ptr) == typeid(pdfString))
addItem( (pdfString*)ptr );
if (typeid(*ptr) == typeid(pdfInt))
addItem( (pdfInt*)ptr );
if (typeid(*ptr) == typeid(pdfFloat))
addItem( (pdfFloat*)ptr );
if (typeid(*ptr) == typeid(pdfArray))
addItem( (pdfArray*)ptr );
}
}
There are uses of this technique that are at least plausible. One that I've seen involved a class hierarchy whose instances needed to be configured by the user (driven from Python) and then used in performance-critical code (in C++). The base class provided a getType() method that returned an enumeration; the wrapper code in Python called this to discover which interface to offer the user. Cross-language code often forces the use of simple-minded techniques like this based on agreed-upon integer labels.
More generally, sometimes good design principles like MVC encourage this sort of arrangement. Even if the different layers are written in the same language, it's not necessarily a good idea for the underlying model objects to have methods like makeQtWidgets(), since it requires that layer to know not only about the GUI library but also about the layout and control flow of the user interface.
A practical point: to avoid the situation where a derived class fails to specify its type, the base class should require the value in its constructor:
struct Base {
enum Type { derived1, derived2 };
Base(Type t) : typ(t) { /* ... */ }
virtual ~Base()=0;
Type getType() const {return typ;}
// ...
private:
Type typ;
};
struct Derived1 : Base {
Derived1() : Base(derived1) { /* ... */ }
// ...
};
You might as well put the enum of all possibilities in the base class, since there must already be a central registry of the value for each derived class even if it's just on paper. This is a downside beyond the several mentioned by others: this design requires that all the classes be centrally managed, with no possibility for independent extension.
Finally, despite that inflexibility the clients must always confront the ugly possibility of an object of an unexpected type:
void foo(const Base &b) {
switch(b.getType()) {
case Base::derived1: /* ... */ break;
case Base::derived2: /* ... */ break;
default:
// what goes here?
}
}
I have several similar classes inheriting from the same Base-Class/Interface (Base class 1), and they share a couple similar functions, but then also have their own distinct functions. They all also have their own member variables of different classes, and each of those inherits from the same Base-Class/Interface (Base class 2). Is it possible to define a variable in Base class 1, of type Base class 2, then in the actual implementation of classes using Base class 1, have the variable of type Base class 2 be its proper type. Kinda hard to explain, so simplified example below.
//Base-Class 1
class Shape
{
public Shape() {}
ShapeExtra m_var;
//The common functions
public GetVar(){ return m_var; }
}
class Circle : Shape
{
public Circle() { m_var = new CircleExtra(); }
public void CircleFunc()
{
m_var.CircleExtraFunc();
}
}
class Triangle : Shape
{
public Triangle() { m_var = new TriangleExtra(); }
public void TriangleFunc()
{
m_var.TriangleExtraFunc();
}
}
.
.
.
//Base_Class 2
class ShapeExtra
{
public ShapeExtra() {}
}
class CircleExtra : ExtraClass
{
public CircleExtra() {}
void CircleExtraFunc() {//Do stuff}
}
class TriangleExtra : ExtraClass
{
public TriangleExtra() {}
void TriangleExtra() {//Do stuff}
}
.
.
.
So, I need the m_var in the child classes to be kept it as its own unique version. Because right now (w/o the extra CircleExtra m_var;), the GetVar() works, but in CircleFunc, m_var is still type of ShapeExtra, and thus doesn't know that CircleExtraFunc exists. I could cast m_var each time I wanted to do that, but that is repetitive and not worth it in my real-world case. Is there a way to utilize the functions in unique classes based off of ShapeExtra, while keeping the GetVar() function in Shape?
Please ask questions if there is anything I left out.
Simply with inheritance and without using pointers it is not possible, as C++ is a statically-and-strictly-typed language.
You can inherit both the variable and the function, but you'll need to cast function return value.
You can also override the function to make it return the concrete type, but then you have to cast the variable inside the function.
You can also declare the same var with the concrete class in subclasses, but then you just hide the variable in the superclass and inherit nothing.
I'd rather go for a solution using templates. Make the type of the variable a template type and extend the template using a concrete type in subclasses. It'll work perfectly.
It's been a long time since I last programmed in C++ and I beg your pardon if there are errors in the following example. I'm sure you can easily make it work.
template <class S>
class Shape {
S m_var;
//......
public:
S var () {
return m_var;
}
//.......
}
class Circle: Shape <CircleExtra> {
// var method returns CircleExtra
//......
}
Edit:
Regarding some comment, to allow virtual invocation of the method, it is possible to use correlated return types. Something like the following example.
class Shape {
public:
virtual ShapeExtra *var () = 0;
}
template <typename SE>
class ConcreteShape: Shape {
public:
virtual SE *var() {
return &m_var;
}
// Constructor, etc.
private:
SE m_var;
}
Or some variation. Now concrete shapes can benefit from extending the template, as long as SE * is correlated with ShapeExtra * (the type parameter extends ShapeExtra). And you can vall the method transparently through Shape interface.
Using pointers, this is totally possible.
Using your example, you could do something like this:
#include <iostream>
#include <memory>
using namespace std;
//Extras
class ShapeExtra
{
public:
ShapeExtra() {}
void ShapeFunc() { std::cout << "Shape"; }
virtual ~ShapeExtra() = default; //Important!
};
class Shape
{
public:
std::unique_ptr<ShapeExtra> m_var;
//require a pointer on construction
//make sure to document, that Shape class takes ownership and handles deletion
Shape(ShapeExtra* p):m_var(p){}
//The common functions
ShapeExtra& GetVar(){ return *m_var; }
void ShapeFunc() {m_var->ShapeFunc();}
};
class CircleExtra : public ShapeExtra
{
public:
void CircleExtraFunc() {std::cout << "Circle";}
};
class Circle : public Shape
{
CircleExtra* m_var;
public:
Circle() : Shape(new CircleExtra()) {
m_var = static_cast<CircleExtra*>(Shape::m_var.get());
}
void CircleFunc()
{
m_var->CircleExtraFunc();
}
};
int main() {
Circle c;
//use the ShapeExtra Object
c.GetVar().ShapeFunc();
//call via forwarded function
c.ShapeFunc();
//call the circleExtra Function
c.CircleFunc();
return 0;
}
Test it on ideone
Note the use of pointers and a virtual destructor:
By using a virtual destructor in the ShapeExtra base class, you make it possible to destruct an object of any derived class, using a ShapeExtra*. This is important, because
by using a std::unique_ptr<ShapeExtra> instead of a plain C-pointer, we make sure that the object is properly deleted on destruction of Shape.
It is probably a good idea to document this behaviour, i.e. that Shape takes the ownership of the ShapeExtra*. Which especially means, that we do not delete CirleExtra* in the Circle destructor
I decided here to require the ShapeExtra* on construction, but its also possible to just use std::unique_ptr::reset() later and check for nullptr on dereferencing Shape::m_var
Construction order is this: On calling the constructor of Circle, we first create a new CircleExtra which we pass to Shape before finally the constructor of Circle is executed.
Destruction order is Circle first (was created last), then Shape which also destructs the ShapeExtra for us, including (via virtual function) the CircleExtra
I would recommend the following approach:
class ShapeExtra
{
public:
virtual ~ShapeExtra() { }
virtual void SomeCommonShapeFunc() { std::cout << "Shape"; }
};
class Shape
{
public:
virtual ShapeExtra &GetVar() = 0; // Accessor function.
};
Note that the class Shape does not have any data members at all. After that for each derived class you need:
class CircleExtra : public ShapeExtra
{
public:
void SomeCommonShapeFunc() { std::cout << "Circle"; }
};
class Circle : public Shape
{
CircleExtra m_var; // Data member with circle specific class.
public:
virtual ShapeExtra &GetVar() { return m_var; }
};
Implementation of virtual method in Circle will return reference to the base class ShapeExtra. This will allow using this extra in the base class.
Note that pointers and templates are not used at all. This simplifies the overall design.
Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}
I have certain functionality encapsulated in classes which I use in another class. I think this is called composition.
class DoesSomething01
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
private:
DoesSomething01 *m_doesSomething01;
DoesSomething02 *m_doesSomething02;
};
If I have now a ClassB which "knows" ClassA and have to use/execute functionality01 and/or functionality02 of classes DoesSomething01 and/or DoesSomething02 I see two possibilities:
a) Add methods like this to ClassA to provide ClassB direct access to DoesSomething01 and/or DoesSomething02:
DoesSomething01 *getDoesSomething01() { return *m_doesSomething01; }
DoesSomething02 *getDoesSomething02() { return *m_doesSomething02; }
ClassB could then do something like this:
m_classA->getDoesSomething01()->functionality01();
b) Add (in this case four) methods to ClassA which forwards the method calls to DoesSomething01 and DoesSomething02 like this:
void doesSomething01Functionality01() { m_doesSomething01->functionality01(); }
void doesSomething01Functionality02() { m_doesSomething01->functionality02(); }
void doesSomething02Functionality01() { m_doesSomething02->functionality01(); }
void doesSomething02Functionality02() { m_doesSomething02->functionality02(); }
Which option is better and why?
What are the advantages/disadvantages of each option?
First option can be considered a code smell. According to Robert C. Martin's 'Clean Code' it is "Transitive Navigation" and should be avoided. Quoting the author:
In general we don’t want a single module to know much about its
collaborators. More specifically, if A collaborates with B, and B
collaborates with C, we don’t want modules that use A to know about C.
(For example, we don’t want a.getB().getC().doSomething();.)
Second option looks better. It is classical use of Facade pattern. And it is better, because it hides other functionalities of classes DoesSomthing01 and DoesSomthing02. Then you ve'got simplified view of it which is easier to use than 1st option.
Edit: there is also one more thing. You've got two classes which have the same functionalites and are aggregated by other class. You should consider using Stratey pattern here. The your code will look like this:
class DoesSomething
{
public:
virtual void functionality01() = 0;
virtual void functionality02() = 0;
}
class DoesSomething01 : DoesSomething
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02 : DoesSomething
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
DoesSomething* doesSomething(); // Getter
void doesSomething(DoesSomething* newDoesSomething); // Setter
// ...
private:
DoesSomething *m_doesSomething;
};
Then you will need only two method instead of four:
void doesFunctionality01() { m_doesSomething->functionality01(); }
void doesFunctionality02() { m_doesSomething->functionality02(); }
The first scenario is a violation of law of Demeter, which says that a class can only talk to its immediate friends. Basically the problem with the first approach is that any change in the inner classes DoSomething01 and DoSomething02 will trigger a change in Class A as well as Class B because both classes are now directly dependent on these inner classes.
The second option is better as it encapsulates the class B from inner classes but a side effect of this solution is that now class A has a lot of methods that does nothing fancy except for delegating to its inner classes. This is fine but imagine if DoSomething01 has an inner class DoSomething03 and class B needs to access its functionality without directly knowing about it than the class A would need to have another method that would delegate to DoSomething01 that would in turn delegate to DoSomething03. In this case I think it is better to let class B directly know about DoSomething01 otherwise class A is going to have a huge interface that simply delegates to its inner classes.
If there are many classes and/or many methods to be called it makes sense to invent
an interface in the form of an abstract parent class:
class SomeInterface
{
public:
SomeInterface(){}
virtual void functionally01() = 0;
virtual void functionally02() = 0;
}
DoesSomthing01 and other classes would then inherit this class:
class DoesSomthing01 : public SomeInterface
and implement the methods.
If it make sense to associate a key with the instantiation of such a class
you could store these objects in ClassA e.g. using a map (here I
use an integer as the key):
class ClassA
{
private:
std::map<int, SomeInterface*> m_Interfaces;
public:
SomeInterface* getInterface(const int key)
{
std::map<int, SomeInterface*>::iterator it(m_Interfaces.find(key));
if (it != m_Interfaces.end())
return it->second;
else
return NULL;
}
};
From ClassB you could then access them
int somekey = ...;
SomeInterface *myInter = m_classA->getInterface(somekey);
if (myInter)
myInter->functionally01();
This way you have just one access method (getInterface()) independent
of the number of objects.
In order to encode the access to the methods using a key you could
create a map which maps a key onto a closure or a simple switch statement:
in SomeInterface:
public:
void executeMethod(const int key)
{
switch(key)
{
case 1: functionally01(); break;
case 2: functionally01(); break;
default:
// error
}
int methodKey = ...;
int objectKey = ...;
SomeInterface *myInter = m_classA->getInterface(objectKey);
if (myInter)
myInter->executeMethod(methodKey);
Looks like a good case for a Mediator Pattern.
This pattern manage communication between 2 objects that he owns.
My question is more or less identical to the one at Need a design pattern to remove enums and switch statement in object creation However I don't see that the abstract factory pattern suits well here.
I'm currently planning the refactoring/reimplementation of some existing DAL/ORM mixture library. Somewhere in the existing code there is code that looks like this:
class Base
{
static Base * create(struct Databasevalues dbValues)
{
switch(dbValues.ObjectType)
{
case typeA:
return new DerivedA(dbValues);
break;
case typeB:
return new DerivedB(dbValues);
break;
}
}
}
class DerivedA : public Base
{
// ...
}
class DerivedB : public Base
{
// ...
}
So the library responsible for database communication populates a struct with all information about the database entity and then the above create() method is called to actually create the corresponding object in the ORM.
But I don't like the idea of a base class knowing of all its derived classes and I don't like the switch statement either. I also would like to avoid creating another class just for the purpose of creating those Objects. What do you think about the current approach? How would you implement this functionality?
This has been discussed here milliions of times. If you don't want to create a separate factory class, you can do this.
class Base
{
public:
template <class T>
static void Register (TObjectType type)
{
_creators[type] = &creator<T>;
}
static Base* Create (TObjectType type)
{
std::map <TObjectType, Creator>::iterator C = _creators.find (type);
if (C != _creators.end())
return C->second ();
return 0;
}
private:
template <class T>
static Base* creator ()
{
return new T;
}
private:
typedef Base* (::*Creator) ();
static std::map <TObjectType, Creator> _creators;
};
int main ()
{
Base::Register <Derived1> (typeA);
Base::Register <Derived2> (typeB);
Base* a = Base::Create (typeA);
Base* b = Base::Create (typeB);
}
Let's say you replace the switch with a mapping, like map<ObjectType, function<Base* (DatabaseValues&)>>.
Now, the factory (which may or may not live in the base class), doesn't need to know about all the subclasses.
However, the map has to be populated somehow. This means either something populates it (so your knowing about all subclasses problem has just been pushed from one place to another), or you need subclasses to use static initialization to register their factory functions in the map.
No matter what you do, you'll need either switch-case or some other construct that will just hide similar logic.
What you can and should do, however, is remove the create method from your Base - you're totally correct it shouldn't be aware of it's derived ones. This logic belongs to another entity, such as factory or controller.
Just don't use enums. They are not OO construction, that was why JAVA did not have them at the beginning (unfortunately the pressure was too big to add them).
Consider instead of such enum:
enum Types {
typeA,
typeB
};
this construction, which do not need switch (another non OO construction in my opinion) and maps:
Types.h
class Base;
class BaseFactory {
public:
virtual Base* create() = 0;
};
class Types {
public:
// possible values
static Types typeA;
static Types typeB;
// just for comparison - if you do not need - do not write...
friend bool operator == (const Types & l, const Types & r)
{ return l.unique_id == r.unique_id; }
// and make any other properties in this enum equivalent - don't add them somewhere else
Base* create() { return baseFactory->create(); }
private:
Types(BaseFactory* baseFactory, unsigned unique_id);
BaseFactory* baseFactory;
unsigned unique_id; // don't ever write public getter for this member variable!!!
};
Types.cpp
#include "Types.h"
#include "Base.h"
#include "TypeA.h"
#include "TypeB.h"
namespace {
TypeAFactory typeAFactory;
TypeBFactory typeAFactory;
unsigned unique_id = 0;
}
Types Types::typeA(&typeAFactory, unique_id++);
Types Types::typeA(&typeBFactory, unique_id++);
So your example (if you really would need this function then):
class Base
{
static Base * create(struct Databasevalues dbValues)
{
return dbValues.ObjectType.create();
}
};
Missing parts should be easy to implement.