I am new with c++ and I don't completely understand the concept of static variables.
I have a static variable in a class.
class FCCommunication : public OEMThread
{
public:
FCCommunication();
static bool MASTER;
}
I am initializing my code and allocation memory to the FCCommunication in the source file using following two statements
FCCommunication * FCObject = 0;
FCObject = new FCCommunication();
now the question for me is that what will happen if I try to access MASTER variable before the object and memory allocation will be done like this
if(FCCommunication::MASTER)// this gets called before dynamic memory allocation.
{
//do something here.
}
Static member variables are allocated as any other non-member variable with static storage duration. Meaning that they end up in a chunk of data initialized before the program is started, most often called either .bss or .data, depending on if the initalizer is a zero value or not.
So the static member variable is not actually allocated together with the class and the value you initialize it to is set by code executing before the rest of the class is even allocated.
This means that you can actually access static members no matter if any instance of the class exists or not. You can think of them as "global variables with restricted access and scope", because that is exactly what they are.
Meaning that your code is fine.
C++ member static variables (of a class) belong to all instance of that class, and they are initialized before any instances of that class are initialized. So, you can use both FCCommunications::MASTER and FCObject->MASTER to access those static variables with no differences.
One thing you should be careful about is that you have to define those static variable separately. That say, you have to do something like this, outsides the class definition:
bool FCCommunications::MASTER = false;
static members are members initialied to zero for first time it is initialized...
IN otherr words , they belongs to a common pool.
any other object can access it.
scope is within the class
the lifetime is the lifetime of the program.
Related
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 have an array I want it to be a private member variable. The way my program works as implementing selection sort is, main method feeds in the size of the array, and the constructor passes in and creates the new array with given size.
I've done with in Java, but can't figure out in C++.
(After taking a look at other people's post on this web, I figured out I have to make my variable static)
Thank you.
[ArrayS.h]
public:
ArrayS(void);
ArrayS(int max);
~ArrayS(void);
private:
static long a [0];
[ArrayS.cpp]
ArrayS::ArrayS(void)
{
}
ArrayS::ArrayS(int max)
{
long ArrayS::a [max];
nElems = 0;
}
Thank you.
There are two issues with the code above. The first is that in C++ you cannot have an array of size 0. The second one is that for static members of a class, you need to provide a definition in exactly one translation unit:
struct test {
static long a[10];
};
// in a single .cpp
long test::a[10] = {};
Other than that, if you need arrays of a size that is only known at runtime, you cannot use raw arrays. You could use dynamically allocated memory (through new[]) but you are better off using std::vector<long>. Additionally, it is unclear whether you really need the member to be static at all. The static keyword in that context means class member (that is, shared by all code in the program, not per-instance data)
You need to define the variable again, outside the class. whenever you have a static member.
Although g++ compiles c++ code which has arrays of size zero, reconsider if that's what you really want.
I have a static function that needs to access data members of a class. The function can be a member, non member or friend function of the class, but it must be static and it cannot take any arguments. So I cannot pass the data members to it as a parameter nor can I pass the object itself to it.
#include "sundials.h"
#include "CVode.h"
class nBody
{
private:
double masses[];
double** paths;
static int accelerator();
//...
public:
//...
void runODE();
};
int nBody::accelerator()
{
// code that needs to know the values stored in masses[]
}
void nBody::runODE()
{
//...
ODEsetAccelerator(accelerator); //require accelerator to be static int
//with specific parameters
// run the ODE
//record trajectories in paths[][]
}
accelerator is fed to a separate ODE solver which requires accelerator to be type static int and take specified arguments, So I can't pass the masses into accelerator because it will be called by the ODE and not main
is there any way I could make the accelerator function know what the value of masses? I don't care how indirect it is.
Let me start off saying your design is broken. A static method that needs to access non-static members of a class and can't receive parameters?
That aside, sure you can. You can access a global object from inside the static method, that's set to the current object you're trying to manipulate:
extern nBody* currentBody;
//........
int nBody::accelerator()
{
//access currentBody
//since this is a member, you have access to other private members
}
//....
nBody someBody;
currentBody = &someBody;
nBody::accelerator();
If this is the "sundials" and "CVode" that show up on a quick web search:
Use the relevant nBody* as the user_data parameter.
It's described in the documentation of the user function (page 55).
If not, please disregard this answer.
Given your constraints, a horrible solution would be to have a static variable in the class called something like currentNBody of type nBody * and set this to the appropriate instance before running the ODE solver.
You are correctly identifying this as a global variable. Of course this will fail utterly if you're doing anything multi-threaded.
This is what i think you are talking about:
Some processing is creating nBody objects with masses.
Some other processing needs to 'accelerate' them.
You need a way essentially to 'register' nBody objects with the 'acceleration process'.
That could be a static method on the AccelerationProcess object or via some callback via RMI, etc.
It is the accelerator process that holds in its state the nBody object references and thus no reason to have a static method on nBody. That is assuming the objects all live in the same memory space - otherwise things get more complicated.
Consider this class for demonstration purposes:
class test{
private:
int y;
HANDLE handle;
static int x;
public:
test()
int add();
static int sub();
}
test::test() {
[....]
sub = 1;
handle = (HANDLE)_beginthreadex(NULL,0,&test::sub,NULL,0,0);
}
test::sub() {
[....]
_endthreadex(0)
}
I am a little unsure about static methods/variables and I now have a few questions;
1) If I create a class instance of test, and then call delete test, does the static variable get cleaned up too? If not, do I need to cleanup all static variables manually in the destructor using delete() (or is it free())?
2) when the thread running sub() terminates with _endthreadex, is there any manual cleanup to be done on the static method? As you can see, the handle variable is refering to the thread.
Thanks in advance
Static variables have program lifetime. They are created when the program starts, and destroyed when the program ends. Only one exists, and it's not in the individual objects.
The keyword 'static', in this instance, implies that there is only a single instance of the variable in memory and it 'belongs' to class test. Long after the instance of 'test' is gone, the variable test::x will remain around and is accessible by any other instances of 'test' and the static 'sub' function (as it is a private variable). No cleanup is necessary, as there is only this single instance in memory.
If the reason for making it static is so it is accessible in 'sub', you could instead pass it in as a parameter. Alternatively, you could pass in the 'test' instance to the thread method and then it would no longer need to be static as you would be able to call non-static functions on the object.
the static variable persist from one instance of the class to another that's why they are static. If you want them to be instance specific then remove the static keyword.
You should never attempt to deallocate a static variable. If you find yourself wanting/needing to do this, then you probably don't really want to use static at all.
The static int would reside in the BSS or Uninitialised Data Section and so, as others have suggested, it will be available fot the lifetime of the program.