I'm looking for solution of C++ class design problem. What I'm trying to achieve is having static method method in base class, which would return instances of objects of descendant types. The point is, some of them should be singletons. I'm writing it in VCL so there is possibility of using __properties, but I'd prefer pure C++ solutions.
class Base {
private:
static Base *Instance;
public:
static Base *New(void);
virtual bool isSingleton(void) = 0;
}
Base::Instance = NULL;
class First : public Base { // singleton descendant
public:
bool isSingleton(void) { return true; }
}
class Second : public Base { // normal descendant
public:
bool isSingleton(void) { return false; }
}
Base *Base::New(void) {
if (isSingleton())
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
else
return new /* descendant constructor */;
}
Arising problems:
how to declare static variable Instance, so it would be static in descendant classes
how to call descendant constructors in base class
I reckon it might be impossible to overcome these problems the way I planned it. If so, I'd like some advice on how to solve it in any other way.
Edit: some minor changes in code. I have missed few pointer marks in it.
Just to check we have our terminologies in synch - in my book, a factory class is a class instances of which can create instances of some other class or classes. The choice of which type of instance to create is based on the inputs the factory receives, or at least on something it can inspect. Heres's a very simple factory:
class A { ~virtual A() {} };
class B : public A {};
class C : public A {};
class AFactory {
public:
A * Make( char c ) {
if ( c == 'B' ) {
return new B;
}
else if ( c == 'C' ) {
return new C;
}
else {
throw "bad type";
}
}
};
If I were you I would start again, bearing this example and the following in mind:
factorioes do not have to be singletons
factories do not have to be static members
factories do not have to be members of the base class for the hierarchies they create
factory methods normally return a dynamically created object
factory methods normally return a pointer
factory methods need a way of deciding which class to create an instance of
I don't see why your factory needs reflection, which C++ does not in any case support in a meaningful way.
Basing this on the answer by #Shakedown, I'll make Base be templated on the actual type, using the CRTP:
template <class T>
class Base
{
public:
static std::auto_ptr<Base<T> > construct()
{
return new T();
}
};
class First : public Base<First>
{
};
class Second : public Base<Second>
{
};
This is nice because construct is now once again a static member. You would call it like:
std::auto_ptr<First> first(First::construct());
std::auto_ptr<Second> second(Second::construct());
// do something with first and second...
You can create a Singleton class and a NonSingleton class, and make all the descendants inherit one of them.
class Base {
public:
static Base *New() = 0;
}
class SingletonDescendant: public Base {
public:
*Base::New() {
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
}
private:
static Base *Instance;
}
SingletonDescendant::Instance = NULL;
class NonSingletonDescendant: public Base {
public:
*Base::New() {
return new;
}
}
class First : public SingletonDescendant{ // singleton descendant
}
class Second : public NonSingletonDescendant{ // normal descendant
}
It solves the issues that you raised:
How to declare static variable Instance, so it would be static in descendant classes: It exists only in the SingletonDescendant class.
How to call descendant constructors in base class: Using the New function
I have to write construct() method in every descendant; I consider it redundant, as it is obvious what it has to do: Now it is only in SingletonDescendant and NonSingletonDescendant.
How about something like this:
class Base
{
public:
virtual Base construct() = 0;
};
class First : public Base
{
public:
Base construct(){ return First(); // or whatever constructor }
};
class Second : public Base
{
public:
Base construct(){ return Second(...); // constructor }
};
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.
I am trying to implement a factory pattern that consists of
a factory class
an abstract class with protected constructor
inherited classes with private constructors and virtual public
destructors.
I want to make sure that
No other one than the factory can not create any instance
If a new inherited class is defined it will not require any modification on interface class and already defined inherited classes. Juts new class implementation and adding into factory classes create method.
I also do not want to write same-like code(like static factory method per inited) for every inherited class and leave the future developers much work for factory connections.
i.e with pseduo code
class Factory;
class Interface
{
protected:
Interface(){/*Do something*/};
public:
virtual ~Interface(){/*Do something*/}
/*I wish I could do below and it is valid for all inherited
classes but friendship is not inherited in C++*/
//friend Interface* Factory::create(Type)
};
class InheritedA:public Interface
{
private:
InheritedA(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
/*I dont want to do below two lines for every inherited class*/
//friend Interface Factory::create(Type)
//public: Interface* factoryInheritedA(){return new InheritedA();}
};
class InheritedB:public Interface
{
private:
InheritedB(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
};
class Factory
{
static Interface* create(Interface type)
{
switch(type)
{
case A:
return new InheritedA();
case B:
return new InheritedB();
default:
//exceptions etc
}
}
}
int main()
{
Interface* I = Factory::create(A/*or B*/);
return 0;
}
Above code is the cloest I put out. Any suggestions (a speciality of C++, a different design,...) is welcome.
I don't think this a good idea, but here is a way to do this. You create a Tag type which can only be created by the Factory and make all the constructors take a parameter of that type.
class Factory;
class Tag
{
Tag() {}
friend Factory;
};
class Interface
{
public:
Interface(Tag t) {}
virtual ~Interface() {}
};
struct Impl1: public Interface
{
Impl1(Tag t): Interface(t) {}
};
class Factory
{
public:
Interface* makeInstance()
{
return new Impl1( Tag{} );
}
};
void foo()
{
Impl1 i( Tag{} );
}
You will get a compiler error in foo() because Tag::Tag is private.
You could have a templated function:
template<typename Type>
std::unique_ptr<Interface> make_interface() {
// exceptions etc..
}
template<>
std::unique_ptr<Interface> make_interface<InheritedA>() {
return std::make_unique<InheritedA>();
}
template<>
std::unique_ptr<Interface> make_interface<InheritedB>() {
return std::make_unique<InheritedB>();
}
but I really don't see the point in all of this Javaesque boilerplate. Not to mention that you are transforming a compile time information (the type) into a runtime one (via exceptions) for no reason really.
I would just go with:
std::unique_ptr<Interface> ptr_a = std::make_unique<InheritedA>();
std::unique_ptr<Interface> ptr_b = std::make_unique<InheritedB>();
when needed.
It is rarely a good practice to use Factory. I count it as an anti-pattern together with the Singleton. In good design, classess do not concern themselves on how they are created. In your case, when used in Factory, how do you create your class using custom allocator? On stack? In shared memory? In memory-mapped file? From the buffer? In place? This is all really hard to cover in Factory, but do not despair - the simple and elegant solution is ditch the factory!
Hmm... I'm trying to break down my problem...
There is a library with some classes that do almost what I want. I can't change classes of the library so I want to derive them and change what I need.
In this case there is a derived class in the library with two subclasses. Now I derive the class and the subclasses.
In the second sub-class there is a virtual method witch modifies a protected variable from the first sub-class.
I want to override the virtual method with a new virtual method which calls the old virtual wethod an then modify the protected variable again.
Why am I getting the error in mySubClass2 while accessing fResponse?
How can I solve my problem?
class libraryClass : pulic someLibraryBaseClass {
protected:
libraryClass::librarySubClass2 lookUpFunction(int ID) {
//some magic to find the obj
return obj;
}
public:
class librarySubClass2;
class librarySubClass1 {
public:
librarySubClass1(libraryClass baseObj) {
myBaseObj = baseObj;
}
void someCallingFunction(int ID) {
libraryClass::librarySubClass2 obj = myBaseObj->lookUpFunction(ID)
obj->someHandleFunction(this)
cout << fResponse;
}
protected:
friend class librarySubClass2;
unsigned char fResponse[200];
private:
libraryClass myBaseObj;
};
class librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Some Text...\r\n"
}
};
};
class myDerivedClass : public libraryClass {
public:
class mySubClass2 : public libraryClass::librarySubClass2;
class mySubClass1 : public libraryClass::librarySubClass1 {
protected:
friend class mySubClass2;
};
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Add some more Text...\r\n"
}
};
};
Edit: Forgot * in Method of mySubClass2
Possible solution:
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
myDerivedClass::mySubClass1* nowMyObj = (myDerivedClass::mySubClass*) obj;
snprintf((char*)nowMyObj->fResponse, sizeof nowMyObj->fResponse, "Add some more Text...\r\n"
}
};
Now I derive the class and the subclasses.
In your example code, you're only deriving the main class and not the subclass. You have to inherit also the subclass:
class libraryClass : pulic someLibraryBaseClass
{
class librarySubClass1 : public someLibraryBaseClass::someLibrarySubClass1 { };
// ....
};
But that can be done only if the subclass is accessible (protected/public).
As far as I can tell you wonder why you can't access obj->fResponse in
void mySubClass2::someHandleFunction(libraryClass::librarySubClass1 obj) { ... }
Well, obj is of type librarySubClass1 which inherits its share of fResponse from the common ancestor. However, that is the share of a relative of mySubClass2, not yours as you are mySubClass2! You can only access the fResponse member of objects which are known to be of type mySubClass which actually happens to be known to be not the case for a librarySubClass1 object.
Getting access to librarySubClass::fResponse is as if you got free access to your uncle's inheritance from your grandparents. Unless you have a very unusual family sharing its wealth freely among all family members, you probably won't have access to your uncle's inheritance either.
Because fResponse in mySubClass2 is treated as protected and at that point it is outside of libraryClass, it only worked on librarySubClass2 because it is inside libraryClass.
in C++, i have the class Base as a interface class and 2 inheritance class: Base1 and Base2 from Base class like this:
class Base{
public:
virtual void printSomething() = 0;
// Some bla bla code...
};
class Base1 : public Base{
public:
Base1();
void printSomething();
};
class Base2 : public Base{
public:
Base2();
void printSomething();
};
In normal way, in my main.cpp, i have to include following code:
Base *b;
string base_name = "Base1"; // or "Base2"
if(base_name.compare("Base1") == 0){
b = new Base1();
}else{
b = new Base2();
}
So, i want to using Base *b = base_name() instead of if()else() block above. In c++, is this possible, anh how? thanks!
Unlike Java, C++ does not offer native support of the reflection concept. You can write a simple function to construct the specific Base instance. This is called a Factory:
Base* create_base_instance(string name) {
if (name == "Base1")
return new Base1();
if (name == "Base2")
return new Base2();
throw runtime_error("unknown class name");
}
Base *b;
string base_name = "Base1"; // or "Base2"
b = create_base_instance(base_name);
The short answer is no. The long answer is: If you want an idiomatic solution, look up the Factory Method design pattern.
Another approach: You could keep proxy objects keyed in by strings in a map and use that map to create these proxy objects (and clone them when required). This method hides the comparison from the end-user and pushes it deep within the standard library container.
Using std::map to implement the factory pattern.
template<typename T>
struct Factory
{
static Base* Create()
{
return new T();
}
};
typedef std::map<std::string, Base* (*)()> FunMap;
FunMap fun;
void Register()
{
fun.insert(std::pair<std::string, Base*(*)()>("Derived1", Factory<Derived1>::Create));
fun.insert(std::pair<std::string, Base*(*)()>("Derived2", Factory<Derived2>::Create));
}
void CreateTypeDemo2(const std::string& name)
{
Base* bp = fun[name]();
bp->Name();
}
From main, you can call the function this way.
Register();
CreateTypeDemo2("Derived1");
CreateTypeDemo2("Derived2");
You can even do it as shown below. In the method CreateDerived2, you can have different implemention of creating Derived2() instead of default implementation
Factory::Create gives us.
Base* CreateDerived2()
{
return new Derived2();
}
void Register()
{
fun.insert(std::pair<std::string, Base*(*)()>("Derived1",Factory<Derived1>::Create));
fun.insert(std::pair<std::string, Base*(*)()>("Derived2",CreateDerived2));
}
Hope this helps.