Given the class:
class A {
Public:
void foo() {
static int i;
i++;
}
};
How would you change it to prevent i from changing between instances following this example:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 1
o3.foo(); // i = 1
o1.foo(); // i = 2
i.e. allocate memory for i on every instance.
EDIT:
Yes, you can add i as an instance variable, but what if you need these counters in various (independent) functions ? I am looking to limit the scope of the variable only to the function ("in member functions"). It would seem awkward to add variables such as i, c, counter, counter_2 to the class if you need various counters, would it not ?
class A
{
public:
int i = 0;
void foo(){
++i;
}
};
is the normal way: i is now a member variable of the class. Clearly you don't want to use static.
In circumstances where declaring data members become costly(need for sparse members that are not used so often), An instance indepent collection - normally an associative one - may come in handy. Knowing nothing more about the OP's intention, std::map family of classes can be used as first speculation. We need to have one counter per visited object in A::foo, but not for unvisited instances(i.e. A instances not calling A::foo). This was the the simplest first solution I came up with:
void A::foo(){
static std::map<A*,std::size_t> i;
++i[this];
//...
};
Upon call to std::map::operator[] on an object not in the map, the associated value is default constructed in a memory location already zeroed by the allocator( in short words 1st-timers are automatically initialized to 0).
Related
How can I improve the structure of the code below?
I have a nested class. I want to access the parent class which is available as a global vector. The ugly part is when I store the index of the parent class in the child class. Can I do better?
vector<A> vec;
struct A
{
int val;
struct B
{
size_t id; // Index of the parent in the global vector. Doesn't look good!
void func()
{
cout << vec[id].val;
}
};
B b;
};
int main()
{
A a;
a.b.id = vec.size() - 1; // Also ugly!
vec.push_back(a);
}
Firstly you should not make use of global variables at all. It is quite bad practice, as any variable lacking access specification can be altered at any point by the program.
This is not so much of an issue with a small program such as this, but in bigger projects you might end up with some very nasty bugs if you were to continue using global variables.
Next, it makes sense to redefine this struct. There is no explicit rule, but in my opinion a struct should not really contain anything other than data members. It would instead be better to define a class, perhaps containing a struct similar to struct b if that is what you wanted. Personally however that is not how I would approach this problem.
Consider instead defining a class A, you might have a variable for "value". Then you might define a function that is passed a value that you want to assign that assigns a value to the "value" variable of that class.
Then within main you might instantiate a vector of "A"s, then set up a for loop(or some other kind of loop it is your choice after all). That for loop can then iterate however many times you tell it to. Per iteration you could instantiate an "A" object, initialise the value within the object, and then push the object onto the back of the vector of "A"s.
At any point within the scope of the main function you can iterate by another for loop through the vector of "A"s to access by index the the "A" object that is required, through which the value can also be accessed. So long as your for loop is set up to begin iterating from a count of 0, the index value for each element of the vector of "A"s will be the same as the the for loop's control variable at each iteration.
The approach that has been outlined is not the optimal solution, however as with all programming there are a number of solutions to your problem and it is up to you to find which is best. Given the context provided it makes sense not to confuse you further by overloading you with information but there are many ways to improve the potential solution outlined above.
Hopefully this answer shows you another path to the same destination, that perhaps is a little bit cleaner and more manageable. Furthermore as a first time responder I hope I have not made any mistakes myself(please let me know if I messed anything up here other readers)! Good luck with your programming!
I think you will need to pass a pointer of the enclosing class to the nested class to be able to use the enclosed class's non-static members.
See the PIMPL idiom for example here:
Why would one use nested classes in C++?
Could write classes like this:
#include <iostream>
#include <memory>
struct A
{
int val;
int getv() {return val;}
struct B
{
A * my_parent;
B(A * a) : my_parent(a) {}
void func()
{
std::cout << my_parent->val << std::endl;
}
};
std::unique_ptr<B> b;
A();
};
A::A() : b(new B(this)) {}
int main()
{
A a;
a.val = 1;
a.b->func();
}
I have been looking around for a while now and can't seem to find an answer to this.
So, if I have several instances of a class, how can I call a function only once from all instances of that class?
For example, if I have a function called myFunc() within a class called myClass and two instances of that class called class1 and class2, then
class1.myFunc() should return 1,
class2.myFunc() should return 0, and
class1.myFunc() should return 0.
How would I do this?
class myClass{
public:
myClass(){}
int myFunc(){
if (myFuncHasBeenCalled){
return 0;
}
else{
return 1;
}
}
}
myClass class1;
myClass class2;
class1.myFunc(); //would output 1
class2.myFunc(); //would output 0
class1.myFunc(); //would output 0
You can achieve that by
introducing a class variable, using static keyword for it in class declaration
define the class variable in a (separate) code file, with initialisation
check it inside the function, if 0 output 1 else 0
increase (or set to non-zero) afterwards
be careful, using synchronisation mechanisms, in case the calls might be from different contexts/threads/tasks/processes (whatever is applicable in your environment)
(If you show your attempts with static variables and explain the problems you had, this could become more detailed.)
You have several options available: the idea is that you need to have some value that can be accessed independently of the instances of the class. static is the way to do this in all cases (except when it's not).
Option one is best option -- static variable in member functions
The approach I would recommend is using a static variable in the member function; this avoids polluting the class itself and makes it easier for you to maintain a consistent ABI as well as a consistent API, across updates. It is very easy to reason about your code as you're not allowing anything else to access the variable.
Example:
struct S {
int F() const {
static int n = 1;
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
Option two is bad option -- static variable in class
An alternative, which seems to be popular, is to keep a static member variable. This allows you do to the same thing as the previous example, but makes it harder to maintain the API and the ABI across upgrades. It also makes it harder to reason about your code and makes it easier to introduce bugs -- a static member variable is not much different from a global variable.
Example:
struct S {
static int n;
int F() const {
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
int S::n = 1;
Option three is worst option -- global variables
The worst alternative is to use a global variable. I'm not going to give you an example of this -- don't do it. If you must do it anyway (you don't), declare your variables in an anonymous namespace in your .cpp file.
namespace {
int n = 0
}
Options four -- good option
Another approach is to use a static member function. This functions is fully independent of all instance of the class. The only difference in the implementation is that you add static to the function declaration -- otherwise, you can use the first two options. This won't be possible in all situations though.
Caveats and other notes
If you need to use the variable to communicate state between two functions, you have to use one of the global options and cannot use a static variable in a member function.
In all cases, if you're not modifying the instance, you should mark your functions const.
You should really use std::atomic variables
You should use some sort of mechanism that guarantees that your code is threadsafe.
The problem itself:
class B{/*...*/};
class A {
/* members */
NON-static thread_local B var; // and a thread_local variable here
ret_t method(/* args */);
};
I want var to exist independently each thread and each instance.
The larger (complete) problem:
Instances of A are shared across threads. B is some resource necessary to call A::method, and it must be independent with respect to threads to avoid race condition (that is, A::method must have "write access" to var). And the corresponding B are different for different instances of A.
One not fully satisfactory approach I came up with is to have some container (say std::unordered_map<THREAD_IDENTIFIER_TYPE, B>) to store each var corresponding to each thread per instance. However, this neither limit access to vars across threads nor prevent the whole container from being modified. (So that require developer to be careful enough to write safe code.)
I've seen a few post on java ThreadLocal keyword(?) on SO, but none of them seem to provide idea that really works. Any suggestion?
You can't have a non-static member declared thread_local. See cppreference. In particular:
the thread_local keyword is only allowed for objects declared at namespace scope, objects declared at block scope, and static data members.
If you don't want to use pthreads (tricky on Windows), some container is your only option.
One choice is a variant of std::unordered_map<THREAD_IDENTIFIER_TYPE, B>. (You could write a class to wrap it and protect the map with a mutex.)
Another initially attractive option is a thread_local static member of A which maps A* to B will avoid any need for locks.
class A {
static thread_local std::unordered_map<A*, B> s_B;
....
};
usage:
void A::foo() {
B& b = s_B[this]; // B needs to be default constructable.
...
The catch is that you need some way to remove elements from the s_B map. That's not too much of a problem if A objects are actually locked to a particular thread, or if you have some way to invoke functions on another thread - but it's not entirely trivial either. (You may find it safer to use a unique identifier for A which is an incrementing 64-bit counter - that way there is much less risk of the identifier being reused between destroying the A object and the message to remove the B from all the maps being processed.)
If you're willing to use tbb (which is free even though by Intel), you could use their tbb::enumerable_thread_specific<T> template class (which essentially is something like std::unordered_map<thread_id,T> but lock free, I understand). Since the A are shared between threads, one such container per instance of A is required, but it appears B is better declared as a nested type. For example
class A
{
struct B
{
B(const A*);
void call(/* args */);
};
tbb::enumerable_thread_specific<B> tB ([&]()->B { return {this}; } );
void method(/* args */)
{
tB.local().call(/* args */); // lazily creates threadlocal B if required.
}
/* ... */
};
Where available, you could use pthread-functions pthread_getspecific and pthread_setspecific for a getter and a setter for that purpose:
#include <pthread.h>
class A {
private:
#define varKey 100L
public:
int getVar() {
void *mem = pthread_getspecific(varKey);
if(mem)
return *((int*)mem);
else
return 0;
}
void setVar(int val) {
void *mem = malloc(sizeof(int));
*((int*)mem)=val;
pthread_setspecific(varKey, mem);
}
~A() {
void *mem = pthread_getspecific(varKey);
if (mem)
free(mem);
}
};
I need to instantiate many objects from a class, but each one of them needs to be aware of a certain value X that is common for every object of this class, like a global parameter. This is necessary for my constructors to work properly in my objects.
Is there a way to do that without passing the value as a constructor parameter? What I wanna do is use the same variable in all objects so I don't waste RAM.
*in my real situation it's not just an X value, is a 1024-dimmension int vector.
What you want is a static member. "When a data member is declared as static, only one copy of the data is maintained for all objects of the class". e.g.
class myClass {
public:
static int x;
};
I assume you mean that you want a vector of size 1024 as the shared variable across all your classes. You could do this:
class MyClass {
static std::vector<int> s_my_vector;
}
This code would go into your header file. In your cpp file, you'd have to initialize the std::vector. However, I do not recommend this. Class static variables that require constructor calls (i.e. not primitives or POD types) have a lot of gotchas that I'm not planning to go into. I will offer a better solution however:
class MyClass {
static std::vector<int> & GetMyVector()
{
static std::vector<int> my_vector;
static bool initialized = MyVectorInit(my_vector);
return my_vector;
}
static bool MyVectorInit(std::vector<int> & v)
{
v.resize(1024);
...
}
public:
MyClass() {
std::vector<int> & v = GetMyVector();
...
}
static void EarlyVectorInit()
{
GetMyVector();
}
}
In this case, the static local variable ensures that there will only be one copy of my_vector, and you can get a reference to it by calling GetMyVector. Furthermore, the static bool initialized is guaranteed to only be created once, which means that MyVectorInit will only be called once. You can use this method in case you need to populate your vector in some non-trivial way that can't be done in the constructor.
The way I've written it, your vector will be created automatically the first time you need to use it, which is fairly convenient. If you want to manually trigger creation for some reason, call EarlyVectorInit().
If I have two static variables in different compilation units, then their initialization order is not defined. This lesson is well learned.
The question I have: are all the static variables already allocated, when the first one is being initialized. In other words:
static A global_a; // in compilation unit 1
static B global_b; // in compilation unit 2
struct A {
A() { b_ptr = &global_b; }
B *b_ptr;
void f() { b_ptr->do_something(); }
}
int main() {
global_a.f();
}
Will b_ptr point to a valid piece of memory, where B is allocated and initialized at the time of the execution of the main function? On all the platforms?
Longer story:
The compilation unit 1 is Qt library.
The other one is my application. I have couple QObject derived classes, that I need to be able to instantiate by the class name string. For this I came up with a templated factory class:
class AbstractFactory {
public:
virtual QObject *create() = 0;
static QMap<const QMetaObject *, AbstractFactory *> m_Map;
}
QMap<const QMetaObject *, AbstractFactory *> AbstractFactory::m_Map; //in .cpp
template <class T>
class ConcreteFactory: public AbstractFactory {
public:
ConcreteFactory() { AbstractFactory::m_Map[&T::staticMetaObject] = this; }
QObject *create() { return new T(); }
}
#define FACTORY(TYPE) static ConcreteFactory < TYPE > m_Factory;
Then I add this macro on every QObject subclass definition:
class Subclass : public QObject {
Q_OBJECT;
FACTORY(Subclass);
}
Finally I can instantiate a class by the type name:
QObject *create(const QString &type) {
foreach (const QMetaObect *meta, AbstractFactory::m_Map.keys() {
if (meta->className() == type) {
return AbstractFactory::m_Map[meta]->create();
}
}
return 0;
}
So the class gets a static QMetaObject instance: Subclass::staticMetaObject from the Qt library - it is auto-generated in Q_OBJECT macro I think. And then the FACTORY macro creates a static ConcreteFactory< Subclass > instance. ConcreteFactory in its constructor tries to reference of Subclass::staticMetaObject.
And I was pretty happy with this implementation on linux (gcc), until I compiled it with Visual Studio 2008. For some reason AbstractFactory::m_Map was empty on the runtime, and the debugger would not break at the factory constructor.
So this is where the smell of static vars referencing other static vars is coming from.
How can I optimize this code to avoid all these traps?
Yes, the standard allows this.
There are a number of paragraphs in section [basic.life] which start out
Before the lifetime of an object has
started but after the storage which
the object will occupy has been
allocated or, after the lifetime of an
object has ended and before the
storage which the object occupied is
reused or released, any pointer that
refers to the storage location where
the object will be or was located may
be used but only in limited ways.
and there is a footnote which indicates that this specifically applies to your situation
For example, before the construction of a global object of non-POD class type
Short Answer: Its should work as you have coded it. See Ben Voigt Answer
Long Answer:
Do something like this:
Rather than let the compiler decide when globals are created, create them via static methods (with static function variables). This means that they will be deterministically created on first use (and destroyed in the reverse order of creation).
Even if one global uses another during its construction using this method gurantees that they will be created in the order required and thus be available for usage by the other (watch out for loops).
struct A
{
// Rather than an explicit global use
// a static method thus creation of the value is on first use
// and not at all if you don't want it.
static A& getGlobalA()
{
static A instance; // created on first use (destroyed on application exit)
// ^^^^^^ Note the use of static here.
return instance; // return a reference.
}
private:
A()
:b_ref(B::getGlobalB()) // Do the same for B
{} // If B has not been created it will be
// created by this call, thus guaranteeing
// it is available for use by this object
}
B& b_ref;
public:
void f() { b_ref.do_something(); }
};
int main() {
a::getGlobalA().f();
}
Though a word of warning.
Globals are an indication of bad design.
Globals that depend on other globals is another code smell (especially during construction/destruction).
Yes. All are located in .data section, that is allocated at once (and it's not heap).
Putting it another way: if you are able to take its address, then it's OK, because it surely won't change.
If B has a constructor, like A has, then the order that they are called is undefined. So your code won't work unless you are lucky. But if B doesn't require any code to initialise it, then your code will work. It's not implementation-defined.
Ah, but the idea that static variables are "not initialised" is quite wrong. They're always initialised, just not necessarily with your initialiser. In particular, all static variables are created with value zero before any other initialisation. For class objects, the members are zero. Therefore global_a.b_ptr above will always be a valid pointer, initially NULL and later &global_b. The effect of this is that use of non-pointers is unspecified, not undefined, in particular this code is well defined (in C):
// unit 1
int a = b + 1;
// unit 2
int b = a + 1;
main ... printf("%d\n", a + b); // 3 for sure
The zero initialisation guarantee is used with this pattern:
int get_x() {
static int init;
static int x;
if(init) return x;
else { x = some_calc(); init = 1; return x; }
}
which assures either a non-return due to infinite recursion, or, correctly initialised value.