C++ Singleton inheritance issue - c++

I am trying to implement an easy inherited Singleton pattern for my child classes.
Therefore, I am implementing a parent class and, as I want to make things as easy as possible for others to create a new Singleton child class, I need to handle inside the father class constructor all the operations needed for the Singleton implementation for the child classes.
#include <vector>
#include <typeinfo>
#include <iostream>
class Father
{
protected:
Father()
{
for(auto & instance : Father::singletonInstances)
if(typeid(instance) == typeid(this)) // typeid(this) will always be "Father", which is actually the issue
{
// Singleton instance already exists for this class
* this = instance;
std::cout<<"An instance of the given class is already active\n";
return;
}
std::cout<<"Constructed\n";
// Otherwise, mark this as the Singleton instance for this class
Father::singletonInstances.emplace_back(this);
}
public:
Father operator=(Father * inputObj) { return * inputObj; }
private:
static std::vector<Father *> singletonInstances;
};
std::vector<Father *> Father::singletonInstances;
class Child : protected Father
{
public:
Child() : Father() {}
};
class Child2 : protected Father
{
public:
Child2() : Father() {}
};
int main()
{
new Child();
new Child2();
return 0;
}
Output :
Constructed
An instance of the given class is already active
So, to make things clear again :
- The issue is that typeid(this) is always "Father" inside the constructor
- new Child(); new Child2(); should be allowed
- new Child(); new Child(); should not be allowed
- No modifications should be made to the child classes
I know my implementation of the Singleton could look rather strange. I am open to new ideas.
I was able to implement these ideas in JScript, yet in C++ I cannot seem to find a way to make it work.

When a class with inheritance is created the base class constructor is called first, after that the child classes upward in the hierarchy. This means that in the constructor of Father, Child/Child2 is not yet constructed.
Trying to use the object before it's constructed would probably result in Undefined Behavior. C++ tries to protect you from this. Read for example the FAQ Lite. This is not the exact same thing, but related and reading this should give you an idea why typeid would say that the object is a Father.
On cppreference we can read
If typeid is used on an object under construction or destruction (in a destructor or in a constructor, including constructor's initializer list or default member initializers), then the std::type_info object referred to by this typeid represents the class that is being constructed or destroyed even if it is not the most-derived class.
I have seen several ways to implement singletons, the most modern seems to be to return a reference to a static function object. Here is one idea.
#include <iostream>
template <typename T>
T& Singleton() {
static T single;
return single;
}
class Foo {
private:
Foo() {
std::cout << "Constructed" << std::endl;
}
friend Foo& Singleton<Foo>();
public:
void print() {
std::cout << "Foo" << std::endl;
}
};
int main() {
//Foo f; not allowed
Singleton<Foo>().print();
Singleton<Foo>().print();
}
This requires every singleton instance to have a private constructor and to friend the template instantiation. Only the Singleton function will be allowed to construct a Foo and it will only construct 1 copy ever. It's also thread safe and you don't need to worry about clean-up. Other approaches can be found if you google around.

Related

How do you access member functions of a class object from within a different class object that has been created in it?

class Class1 //Would be object mClass1
{
public:
void Function1()
{
a++;
}
private:
int a = 0;
Class2 mClass2;
}
(Editing in a space here to clarify Class2 is not defined after Class1; they are in separate files.)
class Class2 //Would be object mClass2
{
public:
Function2()
{
Function1(); // Would be from mClass1
}
}
So Class1 creates an instance of a Class2 object, and that Class2 object has a member function that wants to access the "parent" object's member function, without using inheritance.
I don't know what I specifically need to search for to learn about this. Does it have to do with dereferencing a new pointer? Constructor type/initialization? Does it have a terminology? "Nested classes" bring up classes defined inside another class, which is not what this is.
Without inheritance there is no way to get the 'parent class'. So instead you should just pass the function as a parameter, maybe in the constructor of class 2 if you use it multiple times. See for example: https://www.cprogramming.com/tutorial/function-pointers.html
You cannot do this. Class2 is not known yet when you define Class1, so the Class1::mClass2 data member cannot possibly be created. But this problem can be solved by defining Class2 before Class1, and implementing Class2::Function2() outside the class and only after Class1.
As for calling Function1() inside Function2(), Class2 needs to know the object on which to call Function1(). You could use a reference member for that that you initialize in the constructor:
// Forward-declaration of Class1 so that Class2 will be able to define
// references or pointers to Class1.
class Class1;
class Class2
{
public:
// Constructor that requires a reference to our parent object.
explicit Class2(Class1& parent)
: parent_(parent)
{ }
// Just declare the function. We need to implement it later, outside
// this class definition because Class1 is not fully known yet and as
// a result we can't have calls to Function1() because the compiler
// doesn't know that function yet.
void Function2();
private:
// This is just a reference, so it works even if Class1 is not fully
// known yet.
Class1& parent_;
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2{*this}; // Pass ourself as the parent object.
};
// Class1 is fully known now, so we can do calls to Function1().
inline void Class2::Function2()
{
parent_.Function1();
}
This will work, but it has an important implication: it disables the assignment operator of Class2. This is probably what you want in this case, because two copies of Class2 should probably not have the same Class1 parent object.
However, I don't see why you need to do this. It complicates matters for no good reason. Why not simply pass the Class1 object that Function2() should use as a function argument instead? So:
class Class1;
class Class2
{
public:
void Function2(Class1& c1_obj);
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2;
};
inline void Class2::Function2(Class1& c1_obj)
{
c1_obj.Function1();
}
So whenever Class1 needs to call Class2::Function2(), just pass *this to it. It's simpler and doesn't have the drawbacks of holding a reference or pointer to another object.
With canonic classes - no way to do this, because Class2 is incomplete within Class1 and if you declare Class2 inside of Class1 (as a nested class), it wouldn't have access to Class1, because Class1 incomplete!
Looks like an unsolvable paradox? It is unsolvable in OOP land, but can be dodged just like Nikos had shown. But the problem of undefined types in some cases can be resolved in C++ or similar concept-oriented languages by using CRTP - Curiously recurring template.
If it is possible or not in your use-case and how complex it would be depending on what purpose you pursue. Here is an example of a paradoxical CRTP behavior - a member of base class is able to call a member of derived class:
#include <iostream>
template < class T>
class Base {
public:
template <class U>
struct Accessor : public U {
static void evoke_foo( T& obj)
{
return (obj.*(static_cast< void(T::*)() >(&Accessor::foo))) ();
}
};
void evoke( )
{
Accessor<T>::evoke_foo( *static_cast<T*>(this) );
}
};
class Derived : public Base<Derived> {
protected:
void foo() { std::cout << "Foo is called" << std::endl; }
};
int main()
{
Derived a;
a.evoke(); // evoke belongs to base.
}
Now if we'd want to determine return type of foo() automatically here, this would become an insanely complex piece of code. Some problems like that are solved in implementations of standard namesake of evoke method.

Abstract class init in the initialization list

I want to understand the following c++ concept. class_a is abstract class and as per abstract class concept we cannot create any instance of it.
i have used the initlization list and abstract class as well but never used following concept.
In the code ,the initlization list of class_b, class_a is initlized. I want to understand what is meaning of initlizing it in the initilization list.
class_b::class_b(int val):nameA::class_a()
in fileA.cpp
namespace nameA
{
class class_a
{
public:
virtual ~class_a(){};
virtual void process()=0;
};
}
in fileb.h file
namespace nameB
{
class class_b : public nameA::class_a
{
public:
class_b(int val);
}
}
in fileb.cpp file
namespace nameB
{
class_b::class_b(int val)
:nameA::class_a() //Want to understand this line...
}
It would be more clear with a slightly richer example. Because if the abstract base class has neither attributes nor methods it is harder to see how it can be initialized.
class NamedProcessor {
std::string name; // a private attribute
public:
NamedProcessor(const std::string &name) : name(name) {}
virtual ~NamedProcessor() {}
// a pure virtual method to make the class abstract
virtual void process() = 0;
std::string getName() {
return name;
}
};
class Doubler : public NamedProcessor {
int value; // a private attribute
public:
Doubler(int initial = 1) : NamedProcessor("Doubler") {
reset(initial);
}
void reset(int initial) {
value = initial;
}
int getValue() {
return value;
}
// the concrete implementation
void process() {
value *= 2;
}
};
int main() {
// Compiler would croak witherror : variable type 'NamedProcessor' is an abstract class
// NamedProcessor wrong("Ill formed");
Doubler doubler;
std::cout << doubler.getName() << "\n"; // name has been initialized...
return 0;
}
Here the abstract class holds an attribute which will be available to subclasses. And this attribute has to be set at construction time because there is no public setter for it. The language has to provide a way to initialize the abstract subclass, meaning not building an object, but initializing a sub-object - here setting the name.
By deriving, every class_b object will contain a class_a sub-object.
Even if you cannot instanciate an object of type class_a, there may be a need of initializing this sub-object. Consider that an abstract class can also have members.
If you have an abstract class in terms of an interface (like in Java), this abstract class obviously needs no initialization. Nevertheless it would get a (empty) default constructor in C++, that you can call explicitly in the initialization list. (If you do not call it explicitly, it will be called implicitly.)
If class is abstract it doesn't mean that it can't have any constructor. It means that you can't use it for creating an independent object.
So here is classic inheritance mechanism:
You creating a child_class object
It calls a child_class() constructor
child_class() constructor calls base_class() constructor to guarantee that fields of base_class are built correct
Then executes child_class() constructor for the rest child_class fields
In your example you call class_a() constructor by yourself, but it will be called anyway. So in sum, it's not about abstract class, it's all about simple inheritance.
You need to have some mechanism for initializing class_a fields if they exists, that's why you can call class_a() constructor even if it's abstract class, otherwise inheritance mechanism just useless.

How to construct a class with an existing base class pointer?

I have one base class and two derived child's (different classes).
I would like to construct one child and then construct a second child which uses the same base class instance like the first child.
In pseudo code this would look like this:
class Parent
{
public:
int x;
};
class ChildA : public Parent
{
void setX() {x=5;}
};
class ChildB : public Parent
{
int getX() {return x;} //Shall return 5 after calling the set method of ChildA first
};
//Creating instances
ChildA* a;
a = new ChildA();
Parent* ptrToBaseClass = a;
ChildB* b;
b = new ChildB(); //How can I set this to the same base class ptr (Parent*) which instance “a” has?
How can this be achieved with passing the base class pointer?
I would like to construct one child and then construct a second child which uses the same base class instance like the first child.
What you would like is not possible. Each base class sub object is stored within the most derived object.
You can use the existing base to copy initialise the base of another object, but they will be separate.
What you could do to achieve something similar, is to use indirection:
struct Parent
{
std::shared_ptr<int> x = std::make_shared<int>();
};
struct ChildA : Parent
{
void setX() {*x=5;}
};
struct ChildB : Parent
{
int getX() {return *x;} //Shall return 5 after calling the set method of ChildA first
};
int main() {
ChildA a;
Parent& a_base = a;
ChildB b {a_base}; // note that the base is copied here
a.setX();
std::cout << b.getX();
}
This way even though the base objects are separate, they both refer to shared state.
A simpler solution is to store the state in static storage (such as static member, as suggested by Ahmet). But this will make the state shared across all instances while the indirection allows exact control over which objects share which state.
You can make the x in Parent class static. This will allow you to do this - although I have to warn you that this is quite a dodgy code and can bite you in the a**.
Of course, then you have to access it with rather than just x; as Parent::x.
EDIT: I seem to got it wrong. If you want the whole base class as 'shared' rather than just x; you need pointers and custom logic to manage it - there is no direct language construct.

Design of Generic Singleton Wrapper class

We are in the process of deprecating ACE libraries in our project which consists of around 120 binaries and in many of binaries we have used ACE_Singleton.Since after deprecating we will not have this class so we are thinking of writing our own generic singleton in our shared library that is common across all these binaries and one of the goals that we want to achieve is if somebody inherit from this class (using CRTP) say Logger and even when Logger constructor is public then also we cannot create two logger object.
To illustrate let's assume my singleton class name is GenericSingleton and my client class is logger then following code should throw error :
class Logger:public GenericSingleton<Logger>
{
public:
Logger()
{
}
};
int main()
{
Logger obj;// first instance no issue
Logger obj1; // second instance is problem as it is inherited from singleton
}
So can somebody suggest me how GenericSingleton should be designed so that while creating second object i should get compiletime error ?
In short is there a way that if my derived class doesn't have private constructor,destructor copy constructor etc. then it can be checked at compiletime using static_assert ?
There's no way for a constructor to know at compile time where or how many times it will be called; constructors are just functions, and functions don't know anything about their contexts. Consider that any static_asserts will be evaluated when the class is compiled, but this can (and almost certainly will!) happen in an entirely different translation unit from code that actually instantiates the class.
In any case, it seems unlikely that this would be helpful, because you must have some way to access singletons throughout your codebase.
Additionally, it's unclear why you want to permit your singletons to have public constructors. If you want to enforce singleton behavior at compile time for a completely arbitrary class just by adding an inheritance declaration, you're out of luck; arbitrary classes can be, well, arbitrarily constructed.
Since you're transitioning from the ACE singleton, I suggest you use a similar API; note that the ACE singleton documentation recommends making your singleton constructors private.
If, however, you just want some way to force your client to write a constructor that can't (easily) be called improperly, you can do something like this:
template <typename T>
class SingletonBase {
protected: class P { friend class SingletonBase<T>; P() = default; };
public:
SingletonBase(P) {}
static T& Instance() {
static T instance { P {} };
return instance;
}
};
(You will also need to delete the base class's copy and move constructors. Here is a working example use case. Note that declaring P's constructor =default does not prevent the singleton class from default-initializing instances of P. )
Now, because the base class constructor takes an argument of type P, the singleton class implementation must pass a P to its parent class constructor. But since the constructor for P is private, the singleton class won't be able to construct an instance of P except by copy or move construction, so its constructor must take an instance of P. But since P itself is protected, only the singleton class and the parent class can actually use it, so effectively the only possible call to the child's constructor must be in the Instance method.
Note that you do not need to explicitly declare and define the singleton-class's constructor, which would be ugly because of the need to use SingletonBase<Singleton>::P. You can simply expose the constructor with a using declaration:
using BASE = SingletonBase<Myclass>;
using BASE::SingletonBase;
You need to make sure that instances of Logger cannot be created outside the function that creates the sole instance of Logger.
Here's a simple implementation.
template <typename T> class GenericSingleton {
public:
static T& instance() {
static T instance_;
return instance_;
}
};
class Logger: public GenericSingleton<Logger>
{
// Make sure that the base class can create the sole instance of
// this class.
friend GenericSingleton<Logger>;
private:
// Makes sure that you cannot create objects of the class
// outside GenericSingleton<Logger>
~Logger() {}
public:
void foo() {}
};
int main()
{
// OK. Call foo() on the only instance of the class.
Logger::instance().foo();
// Not OK.
Logger obj1;
}
My advice would be to separate concerns. There is the concept of a service (such as a logger) and the service may or may not be a singleton. But this is an implementation detail, and therefore a separate concern. The consumer of the service ought to be agnostic of it.
Now, later in the lifecycle of the project, when you realise that singletons were a terrible idea, you can refactor the singleton without having to refactor any code that depends on it.
e.g.:
template<class Impl>
struct implements_singleton
{
using impl_type = Impl;
static impl_type& get_impl()
{
static impl_type _{};
return _;
}
};
struct logger_impl
{
void log_line(std::string const& s)
{
std::clog << s << std::endl;
}
};
struct logger
: private implements_singleton<logger_impl>
{
void log_line(std::string const& s) {
get_impl().log_line(s);
}
};
void do_something(logger& l)
{
l.log_line("c");
}
int main()
{
logger a;
logger b;
a.log_line("a");
b.log_line("b"); // behind the scenes this is the same logger
// but the user need not care
do_something(a);
}

How to propagate friend for derived classes

I want to have a class hierarchy and be able to create objects from it only inside a Factory.
Example:
class Base
{
protected:
Base(){};
virtual void Init(){};
friend class Factory;
};
class SomeClass : public Base
{
public://I want protected here! Now it's possible to call new SomeClass from anywhere!
SomeClass(){};
void Init(){};
};
class Factory
{
public:
template<class T>
T* Get()
{
T* obj = new T();
obj->Init();
return obj;
}
};
int main()
{
Factory factory;
SomeClass *obj = factory.Get<SomeClass>();
}
My problem is that I want to be able to make objects only from Factory, but I don't want to declare friend class Factory in every class derived from Base.
Is there any way to propagate friend in derived classes? Is there any other way to achieve this behavior?
No, it's deliberately impossibile.
Is an issue by encapsulation.
Suppose to have a class "PswClass" that manage any password, that is cascade friend with other class: if I inherit from PswClass:
class Myclass : public PswClass {
.......
}
In this way I can, maybe, have access to field that it would be private.
Friendship is neither inherited nor transitive, as described here: friend class with inheritance.
After a little experimentation, and making some use of this hack How to setup a global container (C++03)?, I think I have found a way give the "factory" unique rights to create the objects.
Here's a quick and dirty code. (Scroll towards the bottom to see the hack.)
class Object {};
class Factory {
public:
// factory is a singleton
// make the constructor, copy constructor and assignment operator private.
static Factory* Instance() {
static Factory instance;
return &instance;
}
public: typedef Object* (*CreateObjectCallback)();
private: typedef std::map<int, CreateObjectCallback> CallbackMap;
public:
// Derived classes should use this to register their "create" methods.
// returns false if registration fails
bool RegisterObject(int Id, CreateObjectCallback CreateFn) {
return callbacks_.insert(CallbackMap::value_type(Id, createFn)).second;
}
// as name suggests, creates object of the given Id type
Object* CreateObject(int Id) {
CallbackMap::const_iterator i = callbacks_.find(Id);
if (i == callbacks_.end()) {
throw std::exception();
}
// Invoke the creation function
return (i->second)();
}
private: CallbackMap callbacks_;
};
class Foo : public Object {
private: Foo() { cout << "foo" << endl; }
private: static Object* CreateFoo() { return new Foo(); }
public:
static void RegisterFoo() {
Factory::Instance()->RegisterObject(0, Foo::CreateFoo);
}
};
class Bar : public Object {
private: Bar() { cout << "bar" << endl; }
private: static Object* CreateBar() { return new Bar(); }
public:
static void RegisterBar() {
Factory::Instance()->RegisterObject(1, Bar::CreateBar);
}
};
// use the comma operator hack to register the create methods
int foodummy = (Foo::RegisterFoo(), 0);
int bardummy = (Bar::RegisterBar(), 0);
int main() {
Factory::Instance()->CreateObject(0); // create foo object
Factory::Instance()->CreateObject(1); // create bar object
}
No, there is no way to inherit friend declaration from base class. However, if you make Base constructor private, instances of derived classes won't be possible to create without Factory help.
As others already said, friendship is not inheritable.
this looks like a good candidate of "Abstract Factory" pattern.
assume "SomeClass"es derived from base are used polymorphically.
declare a abstract factory base, which creates Base objects.
derive each concrete factory from base, override the base creation method...
see http://en.wikipedia.org/wiki/Abstract_factory_pattern for examples
You can't do that. This is done to protect encapsulation. See this post: Why does C++ not allow inherited friendship?
For future reference, another idea that came out of the chat between OP and me, which works with only one use of friend as the OP wanted. Of course, this is not a universal solution, but it may be useful in some cases.
Below code is a minimal one which shows the essential ideas. This needs to be "integrated" into the rest of the Factory code.
class Factory;
class Top { // dummy class accessible only to Factory
private:
Top() {}
friend class Factory;
};
class Base {
public:
// force all derived classes to accept a Top* during construction
Base(Top* top) {}
};
class One : public Base {
public:
One(Top* top) : Base(top) {}
};
class Factory {
Factory() {
Top top; // only Factory can create a Top object
One one(&top); // the same pointer could be reused for other objects
}
};
It is not possible. As others have said friendship is not inherited.
An alternative is to make all class hierarchy constructors protected and add the factory function/class as friend to all the classes you're interested in.