Is the typical C++ implementation of Factory class flawed? - c++

I have the need to implement factory class in C++, but when I was thinking about that, I found one big problem that I couldn't solve, and I found out, that all factory implementation examples around are flawed in the same way. I'm probably the one who is wrong, but please tell me why.
So here is simple "typical" factory implementation, it allows me to register new objects without changing the Factory class.
//fruit.h
class Fruit
{
protected :
int count;
public :
Fruit(int count) : count(count) {}
virtual void show() = 0;
};
// factory.h
/** singleton factory */
class Factory
{
typedef Fruit* (*FruitCreateFunction)(int);
static Factory* factory;
std::map<std::string, FruitCreateFunction> registeredFruits;
public :
static Factory& instance()
{
if (factory == NULL)
factory = new Factory();
return *factory;
}
bool registerFruit(const std::string& name, Fruit* (createFunction)(int))
{
registeredFruits.insert(std::make_pair(name, createFunction));
return true;
}
Fruit* createFruit(const std::string& name, int count)
{
return registeredFruits[name](count);
}
};
//factory.cpp
Factory* Factory::factory = NULL;
//apple.h
class Apple : public Fruit
{
static Fruit* create(int count) { return new Apple(count); }
Apple(int count) : Fruit(count) {}
virtual void show() { printf("%d nice apples\n", count); };
static bool registered;
};
// apple.cpp
bool Apple::registered = Factory::instance().registerFruit("apple", Apple::create);
//banana.h
class Banana : public Fruit
{
static Fruit* create(int count) { return new Banana(count); }
Banana(int count) : Fruit(count) {}
virtual void show() { printf("%d nice bananas\n", count); };
static bool registered;
};
// banana.cpp
bool Banana::registered = Factory::instance().registerFruit("banana", Banana::create);
// main.cpp
int main(void)
{
std::vector<Fruit*> fruits;
fruits.push_back(Factory::instance().createFruit("apple", 10));
fruits.push_back(Factory::instance().createFruit("banana", 7));
fruits.push_back(Factory::instance().createFruit("apple", 6));
for (size_t i = 0; i < fruits.size(); i++)
{
fruits[i]->show();
delete fruits[i];
}
return 0;
}
Ok, this code looks fancy and it works, but here comes the but:
The C++ standard doesn't allow me to define the order in which global (static) variables will be defined.
I have 3 static variables here
Apple::registered;
Banana::registered;
Factory::factory;
The Factory::factory pointer needs to be defined to NULL before the Apple(or Banana)::registered variable, or the Factory::instance method will work with uninitialized value, and behave unpredictably.
So, what am I not getting here? Is the code really working only by an accident? If so, how should I solve the issue?

All global POD data is guaranteed to be initialized to a constant value before any initializers run.
So at the start of your program, before any of the register calls are made and before main is run, the pointer is NULL and all of the bools are false, automatically. Then the initializers run, including your register calls.
Edit: Specifically, from the standard (3.6.2.2: Initialization of non-local objects):
Together, zero-initialization and
constant initialization are called
static initialization; all other
initialization is dynamic
initialization. Static initialization
shall be performed before any dynamic
initialization takes place.

All static variables are initialized before the program begins to run. They are set at compile time and baked right into the executable.
The only issue arises when one static variable depends on another:
In a.hpp:
static int a = 1;
in b.hpp:
extern int a;
static int b = a;
The order in which static variables are initialized is not well defined, so b may or may not be 1 in this example. As long as your variables don't depend on each other, you're fine. Furthermore, is you don't give an initial value, static members are set to zero by default.

I've tended to see the 'instance' method of Factory implemented as follows:
static Factory& instance()
{
static Factory *factory = new Factory();
return *factory;
}
However, the point is that all access to the instance runs through the static instance method. The calls to register the two fruit classes for example use Factory::instance() to obtain the singleton which will guarantee that the initializer for Factory::factory has executed. In my posted alternative implementation the static initialization only occurs the first time the method is called.
The possible issues with Apple::registered and Banana::registered depend on where they might be used from. In the posted code they aren't used at all. If used only within apple.cpp and banana.cpp respectively then there is no issue with order of initialization.

Related

Is there a way to get class object in static function other than passing it as parameter?

Is there a way to get the class object in a class static function other than passing it as function argument? I cannot pass it as argument or make my class singleton.
class test{
public:
int i=10;
test(){}
Static test_static_method(){
// somehow get an object of the class to call class member.
std::cout << classObj->i << "\n";
}
};
I am trying to pass the static function to a C-API that takes in void(*)(). But I need class instance in my function to access the class data. Any help is appreciated.
If you're not going to have too many instances of your class, you can use preallocated "callback pool" -- pre-created functions that you allocate as needed for the callbacks:
#define REP10(P, M) M(P##0) M(P##1) M(P##2) M(P##3) M(P##4) M(P##5) M(P##6) M(P##7) M(P##8) M(P##9)
#define REP100(M) REP10(,M) REP10(1,M) REP10(2,M) REP10(3,M) REP10(4,M) REP10(5,M) REP10(6,M) REP10(7,M) REP10(8,M) REP10(9,M)
typedef void (*callback_fn_t)(void); // or whatever signature you need
class myclass {
static struct callback_t {
callback_t *next;
callback_fn_t callback;
myclass *obj;
} callback_table[100];
callback_t *my_callback;
static callback_t *freelist;
#define CB_FUNC_DECL(M) static void cbfunc##M() { callback_table[M].obj->callback(); }
REP100(CB_FUNC_DECL)
public:
callback_fn_t get_callback() {
if (!my_callback) {
if (!freelist) return nullptr;
my_callback = freelist;
freelist = my_callback->next;
my_callback->obj = this; }
return my_callback->callback;
}
void callback() {
/* this non-static method is called by the callback */
}
myclass() : my_callback(nullptr) { }
myclass(const myclass &a) : my_callback(nullptr) {
// need to manually define copy
}
~myclass() {
if (my_callback) {
my_callback->obj = nullptr;
my_callback->next = freelist;
freelist = my_callback; }
}
};
#define CB_TABLE_INIT(M) { M ? myclass::callback_table+M-1 : 0, myclass::cbfunc##M },
myclass::callback_t myclass::callback_table[100] = { REP100(CB_TABLE_INIT) };
myclass::callback_t *myclass::freelist = &myclass::callback_table[99];
Now if you want to use one of these objects as a callback, you call get_callback to get the function pointer you give to the C library, and it will call the callback method in your class on that object.
** I offer here an addition of a singleton solution although you said you can't, for future readers of this topic, who might see it helpful. Pay attention to the other solution.
The answer to your question is "No" for a reason. Objects are unique, and any object of the same class can (and usually will) contains a different data. When you are talking about static function/members of a class, different objects of the same class, will always contain the exact same data in those static functions/members.
However, if from some reason (probably an architecture bug), you don't care which object you will access using your static function, you can either make your class a singleton (which means that you'll always have only one instance of your class, and you'll always know which object data you'll use), or define an object instance static pointer in your class. Something like that:
class test {
public:
int i = 10;
test *class_obj;
test() {
class_obj = this; // The last object that created
}
Static test_static_method() {
// somehow get an object of the class to call class member.
std::cout << class_obj->i << "\n";
}
};
Read about:
Singleton
C++ Singleton
Static members in C++

beginner's C++ thread-safe singleton design

I wish to create a static Class object which should stay in the memory while the program is running. The object needs to be initialized only once by the init function and the output function will be called in a static method always. Does my code make sense and is it thread-safe?
class Singleton
{
public:
static void init(const int value)
{
static Singleton inst;
inst.Value = value;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
int main()
{
int inputValue = 10;
Singleton::init(inputValue);
cout << Singleton::prnValue();
return 0;
}
New Edit:
Or can I try like this then?
class Singleton
{
public:
static Singleton& init(const int value)
{
static Singleton inst;
inst.Value = value;
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
Addition:
Meyer's singleton example look like
class Singleton
{
public:
static Singleton& init()
{
static Singleton inst;
return inst;
}
private:
Singleton() {};
};
So Isn't my code consistent with Meyer's example?
Try4:
How about this?
class Singleton
{
public:
static Singleton& init(int value)
{
static Singleton inst(value);
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton(value)
{
Value = value;
}
int Value;
};
Added comment:
How to pass argument in a singleton
seems to provide the same answer as Try4.
Abandon Singleton and make Value a const global variable initialized with a helper function.
Example:
// anonymous namespace to bind the global to this file to prevent the static
// initialization order fiasco
namespace
{
const int Value = ReadIniFile("section", "key", default_value);
}
But what if you need to use this variable in other files? The best advice I've got is don't. But if you must, the static initialization order fiasco needs to be overcome. Here's a quick way to do that that is similar to what you've seen so far:
// Lazy loader function similar to Meyers Singleton
int Value()
{
static int value = ReadIniFile("section", "key", default_value);
return value;
}
Usage:
me_function_need_Value(Value());
This ensures that Value is initialized before anyone can try to use it no matter which file in your project needs it. Unfortunately it's now hard to figure out when it goes out of scope, so the problem doesn't really go away. It's just moved from the start of the program to the end where it is a little more manageable. See Destruction order of static objects in C++ .
Ensure no one uses Value after main exits and you'll be safe. Still, use with caution.

Local static variables for each thread

Lets say I have a class that after initialization creates a thread and runs a method in it, within it declares a static variable:
void method()
{
static int var = 0;
var++;
}
If I create more objects of the class, for example 3, then the method will be called 3 times in 3 different threads. After that var will equal 3.
How to accomplish the functionality, where each thread has its own static var that is independent of others. I would appreciate all help.
You can use the thread_local keyword which indicates that the object has a thread storage duration. You can use it like that :
static thread_local int V;
If you want more information about storage class specifiers, you can check CppReference.
This is what the thread_local storage class specifier is for:
void method()
{
thread_local int var = 0;
var++;
}
This means that each thread will have its own version of var which will be initialized on the first run through that function and destroyed on thread exit.
You said, in a comment:
I do want a variable that is specific for each instance of a class
That's precisely what an instance variable is (a.k.a. a per-instance member).
static members and function local variables are not specific to each instance of a class! They are either completely global (one instance per entire executable), or are per-thread if you use C++11 and declare them thread_local.
You absolutely need a member variable. That's the only way to guarantee that the variable will be specific for each instance of the class.
You might argue that you create a dedicated thread per each instance of the class. First of all, it's likely that you shouldn't be doing that. Secondly, if you ever change your mind, and stop creating a per-class thread and, say, use a thread pool instead, your code will instantly break.
So, the proper and straightforward thing is to have it as an instance variable (as opposed to a class variable):
// OK - instance variable
class C { int var; };
// WRONG - class variable and lookalikes
class C { static int var; };
class C { void foo() { static int var; } };
// WRONG - thread variable, but **not** instance variable
class C { static thread_local int var; };
class C { void foo() { static thread_local int var; } };
If you want, you can indicate your intent by including the method's name in the variable name:
class C {
int foo_var;
C() : foo_var(0) {}
void foo() { ... }
};
Finally, if you're OK with a bit more typing, you can use a member wrapper to enforce the scope it's used in:
#include <utility>
#include <cassert>
template <typename T, typename Member, Member member>
class ScopedMember {
T data;
public:
explicit ScopedMember(const T & d) : data(d) {}
explicit ScopedMember(T && d) : data(std::move(d)) {}
ScopedMember() {}
template <Member m, void(*)(char[member == m ? 1 : -1]) = (void(*)(char[1]))0>
T & use() { return data; }
template <Member m, void(*)(char[member == m ? 1 : -1]) = (void(*)(char[1]))0>
const T & use() const { return data; }
};
class C {
public:
C() : m_foo(-1) {}
void granted() {
auto & foo = m_foo.use<&C::granted>();
foo = 5;
assert(m_foo.use<&C::granted>() == 5);
}
void rejected() {
#if 0
// Won't compile
auto & foo = m_foo.use<&C::rejected>();
#endif
}
private:
ScopedMember<int, void(C::*)(), &C::granted> m_foo;
};
int main()
{
C().granted();
return 0;
}
Well, if you want a variable to be different from thread to thread, that variable should not be static. It's looses the point of a static variable, which is, by definition, a variable that:
It's shared by all objects of that class.
It does not need an class instance (object) to be accessed.
The question you're asking it's not a "coding problem", but an architectural one. I don't know what kind of system/app you're developing, maybe you need to approach your problem in a different way.
Ask yourself this questions:
Why do I need threads?
Why do I need this variable to be static?
What information do I need to share between threads and what information I don't want to share?
If you are more specific, maybe I can give you a more specific answer/approach.

Using a Static Class function to create a Singleton object/instance

I am trying to create a static member function that returns a pointer to one instance of the class. Is this possible in C++?
class DynamicMemoryLog
{
// Singleton Class:
public:
static DynamicMemoryLog* CreateLog();
void AddIObject( IUnknown* obj );
void ReleaseDynamicMemory();
private:
// static DynamicMemoryLog* instance;
static bool isAlive; // used to determine is an instance of DynamicMemoryLog already exists
DynamicMemoryLog();
~DynamicMemoryLog();
std::vector <IUnknown*> iObjectList;
};
This function below should create a new instance of the class & return a pointer to that object, but the compiler will not allow me to define a static function of the class if it returns a pointer(I think thats why it wont compile?):
static DynamicMemoryLog* DynamicMemoryLog :: CreateLog()
{
// Post:
if ( !isAlive ) // ( instance == NULL; )
{
DynamicMemoryLog* instance = new DynamicMemoryLog();
return instance;
}
return NULL;
}
The particular error you're getting is that when implementing a static member function, you don't repeat the static keyword. Fixing this should resolve the error.
Independently, there's something a bit odd with your code. You claim that this object is a singleton, but each call to CreateLog will create a new instance of the class. Do you really want this behavior, or do you want there to be many copies? I'd suggest looking into this before proceeding.
Here's the simplest solution, but not thread-safe. For analysis in detail, have a look at this article.
class DynamicMemoryLog
{
public:
static DynamicMemoryLog* GetInstance();
private:
DynamicMemoryLog();
static DynamicMemoryLog* m_pInstance;
}
DynamicMemoryLog* DynamicMemoryLog::GetInstance()
{
if(!m_pInstance)
{
m_pInstance = new DynamicMemoryLog();
}
return m_pInstance;
}
I usually do something like this:
class Singleton
{
public:
static Singleton* get()
{
static Singleton instance;
return &instance;
}
};
This way you won't have any nasty memory management issues.

C++ Initialize class static data member

I have a class which has a number of static function to perform some calculation. However, before the calculation, I need to pass in a data to initialize some of the static data members. Currently I have an init(data) function and a clearResource() function which should be called before and after the use of the class. Is there a better way of doing that?
For example:
classA(){
static int a;
static init(int b) {
a = b;
}
static functionA(){
//perform something based on value of a;
switch(a){
}
}
}
int main(){
classA::init(5);
classA::functionA();
}
Thanks
Avoid using static member functions : have your constructor initialize the data and the destructor clear the resources (see RAII). If the existing class cannot be changed, implement a helper class which calls init from its constructor and clearResource from its destructor.
You can use this kind of design
class A()
{
public:
static int a;
static void functionA(int arg = A::a)
{
if(A::a != arg)
A::a = arg;
...
}
};
int A::a = 0;
int main()
{
A::functionA();
}
You should apply the RAII concept: see this and this questions.
Make the member functions and data non-static, initialize in a constructor and free resources in the destructor. This will guarantee the correct sequence of calls: initialize - perform operations - free resources in the client code.
I'd avoid using static members in this case.
This is your problem. You have a class that does processing on some data. That data, for whatever reason, needs to be shared across all instances of this processing class. Ok then, we have a non-static solution!
class Data : boost::noncopyable
{
public:
Data()
{
// initialise all of our data.
}; // eo ctor
}; // eo class Data
Where you instantiate this class is up to you. It could be a member of an application class that is run at start up, or part of some root. It just needs to be accessible and does not need to be static nor a singleton.
class DataProcessor
{
private:
Data& m_Data;
public:
DataProcessor(Data& _data) : m_Data(_data)
{
}; // eo ctor
}; // eo class DataProcessor