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.
Related
I am programming c++ in Unreal Engine. I have some functions that use variables whose value I need to last in time and that are only used within that function. The problem is that if I declare them as static local variables, when I have several members of the same class they all share the same value, and I would like each class to have its own instance of a local variable that lasts over time. How can I achieve this?
If you really want that level of encapsulation, you could make a separate class for each of your member variables and put the function(s) that operate on that variable in that class. You can then inherit from any number of those separate classes to build a class that has several variables.
Example:
struct func_x {
func_x(int X) : x{X} {}
int function_using_x() {
return x;
}
private:
int x; // only one member variable
};
struct func_y {
func_y(int Y) : y{Y} {}
int function_using_y() {
return y;
}
private:
int y; // only one member variable
};
struct foo : func_x, func_y { // inherit from both
foo(int x, int y) : func_x(x), func_y(y) {}
};
Usage:
#include <iostream>
int main() {
foo f{1, 2};
std::cout << f.function_using_x() << f.function_using_y() << '\n'; // 12
}
you need 2 variables for that.
one for counter (declare local but nut static) and change in one instance and another static for following the first variable;
but notice every time you need that static you should update it
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++
Everyone knows the singleton pattern (very simple exemple) :
class Singleton
{
private:
static Singleton* instance;
public:
static Singleton* GetInstance() { return instance; }
void Foo() {}
};
And the use :
Singleton::GetInstance()->Foo();
I wonder, why this GetInstance() is mandatory. I've tried to find a way to eliminate the call to this function, to be able to write for exemple... :
Singleton->Foo();
... using the class name the same way I use a variable, because of the singleton pattern, and others security like deleting the public constructor for exemple, we are sure that we only have a single instance, so why not "using the class as a variable" (quote, unquote, only syntaxic speaking of course !).
Each time, a C++ rule prohibit following exemples :
Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)
Because :
(1) static Singleton* operator->() { return instance; } is impossible, Class Member Access Operator (->) overload can't be static (see C2801), same for (2) with operator ()
(3) and (4) operators . and :: can't be overloaded
Only solution here : Macros, but I'm actually using macros, and I want to find an other way and avoiding macros for this...
It's only a syntaxic interrogation, I'm not here to debate about pros and cons of singletons, but I wonder why C++ permit so many things for simplify the use syntax of users classes with overloads, user literals, and we can't eliminate this little function from the pattern.
I don't expect a solution (but if there is one, it would be great), it's just to understand why, to know if there is a explanation, a design reason, a security reason or anything else !
Thanks in advance !
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self() in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << '\n';
std::cout << self().i << '\n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
I can think of the following way in C++11:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s and use s->i to access the member of the singleton directly.
Or you can use C++14 way: singleton_v<singleton>->i to access member of the singleton directly.
How do I store an object of a class within the class itself?
I know that I have to use the static keyword to accomplish what I want. Thus the class should look something like:
class my_class {
public:
static my_class instance;
my_class() {
my_class::instance = this
}
};
Below is the exact code as it appears in the class
namespace ArmISA {
class ISA {
protected:
static ISA* isa;
MiscReg miscRegs[NumMiscRegs];
const IntRegIndex *intRegMap;
.....
public:
ISA() {
ISA::isa = this;
...
}
...
};
}
The error I get is:
error: could not convert 'ArmISA::ISA::isa' from 'ArmISA::ISA*' to 'ArmISA::ISA'
my_class::instance = *this; will work, but I hope that you are aware that every time you create a new instance of the class, your instance member will be overwritten. Additionally, this means that instance is a copy of *this and not a reference - changes to one are invisible to the other.
Another option is to declare instance as a pointer, in which case both pointers refer to the same object and then instance = this; would compile:
static my_class* instance;
However, I am not sure what exactly you try to achieve.
this is a pointer. Use my_class::instance = *this.
To initialize a static member variable of non-integral type (or, in C++11, non-constexpr), do that outside the class.
For example:
struct Foo
{
static Foo bar;
double x_;
Foo( double x ): x_( x ) {}
};
// Preferably in an implementation file:
Foo Foo::bar( 3.14 );
The declaration outside the class is always formally the definition, which provides storage for the variable (needed if you ever take the address).
If you want to provide a header-file only module, one alternative is to provide access to the static variable via a function, like this:
struct Foo
{
static Foo& bar()
{
static Foo theBar( 3.14 );
return theBar;
}
double x_;
Foo( double x ): x_( x ) {}
};
Another technique is to inherit from a class template that provides the static variable.
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.