i have the following:
class base
{
public
void f();
...
}
void base::f()
{
static bool indicator=false;
.....
if(!indicator)
{
...
indicator=true;
}
}
class D:public base
{
...
}
in my main() i have:
main()
{
// first instance of D
base *d1 = new D();
d1->f();
....
// 2nd instance of D
base *d2 = new D();
d2->f();
}
i find that the first time i instantiate D and call d1->f() the static variable is set to false. but the 2nd time i call d2->f() the code does not even hit the line "static bool indicator=false;" and it is kept at true (from the first pass of d1-f()) This is exactly the behavior i want but i do not understand why this is happening. can someone please explain what is happening. thanks in advance
Static variables declared in member functions will keep their value between function calls. There will be only one copy over all instances, and all accesses to indicator from different instances will affect the same indicator. This means indicator will only be initialized once.
See here for more info: Static variables in member functions
Also this code does not toggle indicator, it always sets it to true if it's false (which I'm sure is the behaviour you want).
if(!indicator)
{
...
indicator=true;
}
This is precisely the behavior of static variables declared inside function blocks. It has been like that since the introduction of the feature in the C programming language.
The static declaration can also be applied to internal variables. Internal static variables are local to a particular function just as automatic variables are, but unlike automatics, they remain in existence rather than coming and going each time the function is activated. (K&R, page 61).
The static initializer is executed before the first invocation of the containing function. Being static, the variable retains its last state across the invocations.
Related
I have a C++ program with three source files:
// main.cpp
auto return_value = managed_call(int value);
// managed.cpp
#include "private_impl.hpp"
int managed_call(int arg) {
if (arg == 0)
return private_func();
else
return arg;
}
//private_impl.cpp
static some_type some_var = construct_static_object_might_blow();
int private_func() {
....
return 42;
}
My question is about the initialization of the static object in private_impl.cpp: "when does that take place?" or more specifically - is it only initialized if the private_func function is called?
Update
I actually simplified the example a bit too much; the code in question will be run as a Python extension - i.e. it is dlopen()which is the crucial init step. This SO question turned out to be spot on.
When is the static init called in C++
I suppose that you mean, when is the variable with static storage duration initialised. If the variable has static initialisation, that happens before anything else.
If the variable has dynamic initialisation, then it is initially zero initialised during the static initialisation. The exact point of dynamic initialisation is implementation defined. The variable will be initialised at some point before it - or any other variable from that translation unit (TU) - is accessed the first time, or before any function from that TU is called.
is it only initialized if the private_func function is called?
It may be initialised whether private_func is called or not. But if private_func is called, then the variable will be initialised at some point before the function call. It is unclear to me whether the initialisation can be deferred so far that it never happens.
Relevant standard quotes in this SO post.
You have no guarantee about the order that static global objects are initialized in across compilation units. See https://isocpp.org/wiki/faq/ctors#static-init-order - you do have guarantees within a translation unit though.
The best way to not get bitten by this is to not have globals (singletons) in the first place.
Non-local static variables are initialized when their compilation unit is initialized. The standard demands that a compilation unit is initialized no later than when an element from it is accessed first, so in your example construct_static_object_might_blow() will definitely be called before the first call of private_func(). The compiler may initialize private_impl.cpp's translation unit before calling main(), but this is nothing you should rely on.
A way to get by the static init, is by making a late init of the object.
Something like this
class some_class
{
public:
some_class() {} // do nothing
~some_class() {} // do nothing either
void set(some_type value) { val = value; }
some_type get() { return val; }
void shutDown { // do some cleanup }
private:
some_type val;
}
static some_class g_SomeClass ;
int main()
{
g_SomeClass.set("something");
g_SomeClass.shutDown();
return 0;
}
If your class need a proper way to shutdown, then you must do that by calling the shutdown.
Could that be a solution ?
So I have experience using programming languages and just switched over to C++. Now I have created a few working applications but I always stumble upon the same problem. I don't exactly know what everything is called in the code. You have a class which obvious to see since the has written class before it. And you also have some sort of functions attached to the class are these called instances? And is the class the object it referring to by for example class::function.
But my main question was how can I access the variables from another function within the same class file. I have included an example below explaining what I want to achieve. I already tried a lot of things and googled a lot. I tried code pasting code creating setting and getting functions, calling the class to get and set the variable but I can't get it to work. I've spend a lot of time fixing this very basic problem. Could someone explain me what is called what in this code (Class,Object,Instance). And explain me the most efficient way to receive data from another function in the same .cpp file.
Thanks
load_data.h
#pragma once
class load_data
{
public:
static int data[13];
load_data();
static void test2();
};
load_data.cpp
#include "load_data.h"
#include "abc.h"
load_data::load_data()
{
int data[3]; // Initializing the array
data[0] = abc::LoadImage("textures/1.png");
data[1] = abc::LoadImage("textures/2.png");
data[2] = abc::LoadImage("textures/3.png");
}
void load_data::test2()
{
abc::CreateSprite(1, data[0]);
abc::SetSpritePosition(1, 0, 0);
abc::SetSpriteScale(1, 3, 3);
// Now I get an error saying it has no data. Which however is set in
// load_data(). But since each function gets its own variables this one will be empty.
abc::CreateSprite(2, data[1]);
abc::SetSpritePosition(2, 64, 64);
abc::SetSpriteScale(2, 3, 3);
abc::CreateSprite(3, data[2]);
abc::SetSpritePosition(3, 128, 128);
abc::SetSpriteScale(3, 3, 3);
}
Change your load_data() constructor to the following (currently, your creating a new data[] variable that is locally scoped to your load_data() constructor, which gets initialized instead of your object's data[] (gets "eclipsed"). Your subsequent call to test2() fails when it accesses data[] because the other, local data[] was initialized instead. Also, fyi, the local data[] is destroyed when load_data() returns (because it is an auto/stack variable that falls out of scope).
load_data::load_data()
{
//int data[3]; // Initializing the array
data[0] = abc::LoadImage("textures/1.png");
data[1] = abc::LoadImage("textures/2.png");
data[2] = abc::LoadImage("textures/3.png");
}
you also have some sort of functions attached to the class are these
called instances?
An object is an instance of a class. A class defines the object type, which consists of state variables, and operations for them (known as "member functions" or "methods").
An object's methods are called through a handle to the instance. IE, an instantiated variable:
load_data ld = new load_data();
ld.test2();
And is the class the object it referring to by for example
class::function.
This notation is for explicitly qualifying a method name. It helps resolve naming conflicts and should only be used when needed (otherwise it is implicit).
But my main question was how can I access the variables from another
function within the same class file.
...
But since each function gets its own variables this one will be empty
All functions of a class share the class'es (member) variables. An given instance of the class has the only copy of those member variables (ie, their specific values/memory to that instance), so all method calls through a specific instance variable (say ld) of load_data will refer to the same data[] array (so load_data ld1, ld2 would each have their own copies). Functions can, and usually do, declare their own variables to help assist in computing the task they perform (bools, counters, etc...). These such variables, as mentioned before, are scoped to that function, meaning they're no longer allocated and get destroyed when the function returns (they are auto-variables).
And you also have some sort of functions attached to the class are
these called instances?
No. the functions inside of the class are called "class member function" or just "member functions". An instance is a copy of that object (read class) in memory. So in short:
class A {
public:
void fun (void); ///< This is a class member function
};
void main (int argc, char *argv[]) {
A a; ///< a is an instance of object A
}
And is the class the object it referring to by for example
class::function.
The class defines the object. In the above snipped, A is an object.
But my main question was how can I access the variables from another
function within the same class file.
You need to do some reading on variable scope. In your above example the data array is local to the constructor. It doesn't exist within the object, only within that function. So as soon as the constructor finishes, the variable goes out of scope and is lost. In order to keep it in the object's scope you would need to declare it within the object.
class load_object {
public:
// The same
private:
int load[3];
};
Cheers
I came across the following structure in a C++ library:
In myClass.h
class myClass {
public:
static myClass* Instance();
.
.
private:
static myClass* _instance;
.
.
};
and in myClass.cpp
myClass* myClass::_instance = NULL;
// followed by the all other functions..
myClass::myClass() {
.
.
}
myClass* myClass::Instance() {
if (_instance == NULL) {
.
.
}
.
.
}
So what is the use of making the _instance to be NULL pointer outside any function? And when is this line of code executed?
Thank you.
Edit:
Adding the main function. And the instance function in myClass.cpp that checks for the value of the pointer. Still don't understand when the pointer get set to NULL though.
int _tmain(int argc, T_CHAR* argv[]) {
myClass* instance = myClass::Instance();
.
.
.
return 0;
}
So what is the use of making the _instance to be NULL pointer outside any function?
Static data members usually have to be defined, in the namespace containing their class, in one source file; they are subject to the One Definition Rule, and so must have exactly one definition in any program that uses them. This is that definition.
Initialising it with NULL makes sure it's initially null, so that the Instance() function can determine whether the instance has been created yet. This isn't strictly necesssary since, like all static variables, it will be zero-initialised whether or not you explicitly provide an initialiser.
And when is this line of code executed?
During static initialisation, before any other code in the program; since it's a trivial type with a constant initialiser.
I have stumbled upon something like this once. It was something similar to singleton. The reason (as explained by the person doing it) was that he specifically wanted to initialize instance at the first getInstance() function call and he wanted to make sure that the _instance pointer will be at first initialized to NULL (and not some garbage from memory) so that the check
if (_instance == NULL)
in the function works properly.
I am not sure this is the case here, but it's possible.
myClass* myClass::_instance = NULL;
the code attempts to initialize the static member variable.
It's an initialisation, ensuring that the pointer starts life with the value NULL from the very beginning of the program.1
It gives the pointer an invalid, but recognisable and testable value before some useful pointer value is assigned to it later on during the program. This way, you can safely test the pointer to see whether it was yet given said useful value.
In this case, since you are showing a singleton, "later" means "when an instance of myClass is first requested" using some myClass::getInstancePlease() function that you have not shown.
It is more common to implement a singleton with a function-static instance, rather than a class-static pointer to some [probably dynamically-allocated] instance.
1 As an object with static storage duration, it would do so anyway; therefore, this initialisation is actually completely pointless beyond documenting programmers' intent.
Static keyword means it is being shared by all the objects that will be instantiated by the class. Hence you need to initialize it outside any function.Static states that it is a class variable shared between all the instance of the class. It is opposite to instance variables, which each instance has its own copy. To access a class variable, there are two ways. 1) a_class::static_variable 2) a_class a; a.static_variable. The initialization must go in the source file (.cpp) rather than in the header.
Because it is a static variable the compiler needs to create only one copy of it. If you don't, you get a link error. If that is in a header you will get a copy in every file that includes the header, so get multiply defined symbol errors from the linker.
Static data members are not part of objects of a given class type; they are separate objects. As a result, the declaration of a static data member is not considered a definition. The data member is declared in class scope, but definition is performed at file scope.
I am learning C++ by making a small robot simulation and I'm having trouble with static member functions inside classes.
I have my Environment class defined like this:
class Environment {
private:
int numOfRobots;
int numOfObstacles;
static void display(); // Displays all initialized objects on the screen
public:
Robot *robots;
Obstacle *obstacles;
// constructor
Environment();
static void processKeySpecialUp(int, int, int); // Processes the keyboard events
};
Then in the constructor I initialize the robots and obstacles like this:
numOfRobots = 1; // How many robots to draw
numOfObstacles = 1;
robots = new Robot[numOfRobots];
obstacles = new Obstacle[numOfObstacles];
Here is example of static function that uses those variables:
void Environment::display(void) {
// Draw all robots
for (int i=0; i<numOfRobots; i++) {
robots[i].draw();
}
}
When I try to compile, I get error messages like
error: invalid use of member ‘Environment::robots’ in static member function
I tried making numOfRobots, numOfObstacles, robots and obstacles static, but then I got errors like
error: undefined reference to 'Environment::numOfRobots'
I would greatly appreciate of someone could explain me what I am doing wrong.
Thank you!
Static methods can't use non-static variables from its class.
That's because a static method can be called like Environment::display() without a class instance, which makes any non-static variable used inside of it, irregular, that is, they don't have a parent object.
You should consider why you are trying to use a static member for this purpose. Basically, one example of how a static method can be used is as such:
class Environment
{
private:
static int maxRobots;
public:
static void setMaxRobots(int max)
{
maxRobots = max;
}
void printMaxRobots();
};
void Environment::printMaxRobots()
{
std::cout << maxRobots;
}
And you would have to initialize on the global scope the variables, like:
int Environment::maxRobots = 0;
Then, inside main for example, you could use:
Environment::setMaxRobots(5);
Environment *env = new Environment;
env->printMaxRobots();
delete env;
There are 2 issues here - the algorithm you're trying to implement and the mechanics of why it won't compile.
Why it doesn't compile.
You're mixing static and instance variables/methods - which is fine. But you can't refer to an instance variable from within a static method. That's the "invalid use" error. If you think about it, it makes sense. There is only one "static void display()" method. So if it tries to refer to the non-static (instance) variable "robots", which one is it referring to? There could be 10 ... or none.
The logic you are trying to implement.
It looks like you want a single Environment class that manages N robots. That's perfectly logical. One common approach is to make Environment a 'singleton' - an instance variable that only allows for a single instance. Then it could allocate as many robots as it want and refer to them freely because there are no static variables/methods.
Another approach is to just go ahead and make the entire Environment class static. Then keep a (static) list of robots. But I think most people these days would say option #1 is the way to go.
static members are those that using them require no instantiation, so they don't have this, since this require instantiation:
class foo {
public
void test() {
n = 10; // this is actually this->n = 10
}
static void static_test() {
n = 10; // error, since we don't have a this in static function
}
private:
int n;
};
As you see you can't call an instance function or use an instance member inside an static function. So a function should be static if its operation do not depend on instance and if you require an action in your function that require this, you must think why I call this function static while it require this.
A member variable is static if it should shared between all instances of a class and it does not belong to any specific class instance, for example I may want to have a counter of created instances of my class:
// with_counter.h
class with_counter {
private:
static int counter; // This is just declaration of my variable
public:
with_counter() {++counter;}
~with_counter() {--counter;}
static int alive_instances() {
// this action require no instance, so it can be static
return counter;
}
};
// with_counter.cpp
int with_counter::counter = 0; // instantiate static member and initialize it here
The first error says that you cannot use non-static members in static member functions.
The second one says that you need to define static members in addition to declaring them You must define static member variables outside of a class, in a source file (not in the header) like this:
int Environment::numOfRobots = 0;
You don't need any static members. To have an absolutely correct and portable GLUT interface, have a file-level object of type Environment and a file-level (non-member) function declared with C linkage. For convenience, have also a member function named display.
class Environment
{
public:
void display() { ... }
...
};
static Environment env;
extern "C" void display () { env.display(); }
A static member function is one that can be called without an actual object of that kind. However, your function Environment::display uses the variables numOfRobots and robots, which both live in a particular instance of the Environment class. Either make display non-static (why do you want it to be static?) or make the robots static members of Environment too.
In your case, I don't see a reason for making display or processKeySpecialUp static, so just make them normal member functions. If you wonder when a member function should be static, consider if that function would make sense if no objects of that class have been created (i.e. no constructors been called). If the function doesn't make sense in this context, then it shouldn't be static.
A static method cannot access instance variables. If you want to access instance variable remove static from the method. If those values can be the same through all robot instances then make them static variables and the method can remain static.
if you want to access member variables in static member function just create a static pointer of the member variable and use it in the function !!!!!
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.