I know that static members don't belong to objects.
But why is it so?
And when is the memory for static data members allocated?
I know that static members don't belong to objects. But why is it so?
Because you use static members whenever you have some quantity that all objects
"share", say for example the number of instances class Foo has. Such a "shared" member cannot belong to a particular instance. When a new Foo object is being created, then the static variable num_instances is incremented. If the variable wasn't static, then each new Foo will start with a clean state, and couldn't possibly know about other Foo's. Example:
#include <iostream>
class Foo
{
static int num_instances; // all instances share this variable
public:
Foo()
{
++num_instances; // increment the number of instances
}
static int get_num()
{
return num_instances;
}
};
int Foo::num_instances = 0;
int main()
{
Foo foo1, foo2;
std::cout << "We have " << Foo::get_num() << " Foo's" << std::endl;
}
And when is the memory for static data members allocated?
The memory for static objects is allocated before program startup.
Related
I'm doing C++ after along time , i had declared a static variable inside the class as private and as far i know the static variables are independent of objects and shared across the objects .If i try to print the static variable outside the class using a class name i get the compilation errors is this because the variable is private ? I did read that the static variables can be accessed just by the Class name and the scope resolution operator .
#include <iostream>
using namespace std;
class Sample{
int val;
static int value;
public:
Sample(int in);
Sample();
void setval(int in){
val = in;
}
void printval ()const{
cout << val<<endl;
}
};
Sample::Sample(int in){
val = in;
}
Sample::Sample(){
val = 0;
}
int Sample::value = 34;
int main()
{
const Sample obj(1);
Sample obj2;
obj2.printval();
obj.printval();
cout <<"static value = " << Sample::value;
return 0;
}
Error
main.cpp:37:5: error: 'int Sample::value' is private
int Sample::value = 34;
^
main.cpp:49:39: error: within this context
cout <<"static value = " << Sample::value;
as far i know the static variables are independent of objects and shared across the objects
That is correct. However, sharing variables across object instances and making variables accessible are independent of each other. There are four combinations of (shared, accessible) pairs. All four are available to you:
public static variable is shared and accessible outside the class
private static variable is shared, but not accessible outside the class
public non-static variable is not shared, but accessible outside the class
private non-static variable is neither shared nor accessible outside the class
Note that the way you deal with the private static value can be modeled after the way you work with non-static val, i.e. by giving your class users some public member-functions to work with the static variable:
class Sample {
...
public:
static int getvalue() { return value; }
};
Now you can print it like this:
cout << "static value = " << Sample::getvalue();
Private class members and methods are accessible only by the class's members and methods. This is true whether the class member is static, or not. This has no influence on the accessibility of the class member.
Note that a public class method has access to private class members, just like any other method, and this does not preclude a public class method from returning a pointer or a reference to the private class members. That's one option for you.
If I have a class like
class MyClass {
public:
int myMember1;
int myMember2;
int myMember3;
};
Every time I instantiate an object of MyClass space for three consecutive int is allocated, what about when I have something like
class MyClass {
public:
static int myMember1;
int myMember2;
int myMember3;
};
How the memory is allocated this time?
I'm asking because I'm not entirely sure how the memory would be allocated when I declare multiple instance of the same class, is there a pointer to the static member maybe?
As others already stated, you have to explicitly allocate space for the static member variable outside the class definition.
In response to your other question, static member variables are not associated with class objects. That is to say, they will continue to exist even after your MyClass object has ceased to exist (until the termination of your program), and be shared across all instances of your class.
Say you created multiple instances of the MyClass class like so:
class MyClass {
public:
static int myMember1;
int myMember2;
int myMember3;
};
int MyClass::myMember1 = 1;
int main()
{
MyClass mc1;
MyClass mc2;
mc2.myMember1 = 2;
std::cout << mc1.myMember1 << '\n';
std::cout << mc2.myMember1 << '\n';
return 0;
}
The output will be:
2
2
How the memory is allocated this time [with the static member]?
Each instance of the object will have 2 integers in, and all instances have access to the static integer (but don't "own" it) - it is not part of the instances, it is in the scope of the class.
N.B. the member is declared in the class, but must be defined outside the class (in the cpp file), e.g.;
int MyClass::myMember1 = 42;
... is there a pointer to the static member maybe?
No. You can get a pointer the static member if you require, but one is not allocated to each instance.
The static member is allocated (and initialised as per the initialisation in the cpp file) when the application launches and can be accessed as other "global" objects are (albeit that the static is not in the global namespace, there is only one instance of it). The accessibility of the member (i.e. public, private vs. protected) follows the normal rules.
To see the effect on the size, you can use sizeof();
class MyClass {
public:
int myMember1;
int myMember2;
int myMember3;
};
class MyClass1 {
public:
static int myMember1;
int myMember2;
int myMember3;
};
int MyClass1::myMember1 = 42;
int main(int argc, char* argv[])
{
using namespace std;
cout << sizeof(MyClass) << " " << sizeof(MyClass1) << endl;
}
The above (depending on alignment and the size of the int), could produce an output of 12 8.
Demo
You have to define the variable outside the class also. That is where the actual allocation will be done.
In essence it is the same as a global variable.
class Test
{
public:
static int too; // Just a declaration
};
int Test::too; // Actual allocation, every instance will use this
You have to explicitly allocate memory for that static member somewhere.
For example, your class in in it's header file:
// myclass.h
class MyClass {
public:
static int myMember1;
int myMember2;
int myMember3;
};
And you have a cpp file for that class, which explicitly allocates space for that static member, it can also initialize it:
// myclass.cpp
int MyClass::myMember1 = 5;
So your static member will be allocated at exactly one place in your program, in the translation unit of your choice. You can place this allocation into any file you want, as long as it is only part of one translation unit.
Static membes are allocated in static memory
You could think in these members as global variables, but declared inside the class scope (with corresponding access, in your case, public).
When we declare a member variable static, it is shared between all instances of the class. I've heard that you should think of the variable belonging to the class itself, not any instance. This lets us initialize the variable without instantiating any object of the class, which makes sense.
class Something
{
public:
static int s_nValue;
};
int Something::s_nValue = 1;
But why are we allowed to initialize a private static member?
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1;
Does private even mean anything when we are talking about static members?
Yes, it does mean something. Consider the following example, which throws a compiler error, because the member is private. Being able to initialize a private variable is not the same as being able to change it from any context.
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1;
int main(){
Something::s_nValue = 2; // Compiler error here.
}
Private still means the same thing: you cannot use the name Something::s_nValue except in the definition of a member of Something (or a friend, or a nested class within Something).
int Something::s_nValue = 1;
is the definition of a member of Something - namely, that static member s_nValue.
int Something::another_static_val = s_nValue; // also okay
int OtherClass::x = Something::s_nValue; // Illegal access!
int Something::getValue() const {
return s_nValue; // okay, getValue is a member of same class
}
int regularFunction() {
return Something::s_nValue; // Illegal access!
}
Does private even mean anything when we are talking about static members?
I'll try to answer with a classic example. Consider the following piece of code:
#include <iostream>
class foo {
static int count;
int id;
public:
foo() : id(++count) {}
int getid() const { return id; }
};
int foo::count = 0;
int main() {
foo f1, f2, f3;
std::cout << f1.getid() << std::endl;
std::cout << f2.getid() << std::endl;
std::cout << f3.getid() << std::endl;
}
LIVE DEMO
In the example above we use a private static int to count the instances of foo created. We made the count static member variable private because we don't want anyone else except object of type foo to mess with it.
And this is only a naive example, think of the possibilities.
Public, private and protected are properties of a class and not of an object. Their purpose is to let you specify which parts of this class are visible to other classes, and not to hide stuff from objects of the same class. So, you can write code like this :
class A
{
public:
bool operator<(const A& other)
{
return this->val < other.val;
}
private:
int val;
};
So, private makes sense even when applied to static members - it just says that other classes cannot see this member.
Is there a way through which we can get all the objects of a class in C++.Like in Python we can do
class_name.objects.all()
to get all the objects of a class.What's its analog in C++,if it exists?
You can do this yourself, but make sure you know what you're doing.
How:
There's nothing within C++ that already does this, but it's pretty easy to do this yourself. The key is to recognize that a class can have static member variables and functions (i.e. functions that belong to the whole class, rather than to individual objects of the class).
So you can use some kind of table or other data structure to store a reference to each object. Like so:
class A {
public:
//constructor assigns this object an id based on the static value curID,
//which is common to the class (i.e. the next class to call the constructor
//will be assigned an id thats 1 more than this one
//also, constructor adds the pointer to this object to a static map of ids
//to objects. This way, the map can be queried for the pointer to an object
//that has a particular id
A() {
id = curID++;
objects[id] = this;
}
//copy constructor ensures an object copied from another does not
//take the id of the other object, and gets added to the map
A(const A&) {
id = curID++; //don't want have the same ID as the object we are copying from
objects[id] = this;
x = A.x;
y = A.y;
}
A& operator=(const A&) {
id = curID++;
objects[id] = this;
x = A.x;
y = A.y;
return *this;
}
//destructor removes the pointer to this object from the map
~A() {
objects.erase(id);
}
//function to get the map that stores all the objects
static map<int, A*>& GetMapOfObjects() {
return objects;
}
private:
//the following variable is **static**, which means it does not
//belong to a single object but to the whole class. Here, it is
//used to generate a unique ID for every new object that's
//instantiated. If you have a lot of objects (e.g. more than
//32,767), consider using a long int
static int curID;
//this variable is also static, and is map that stores a pointer
//to each object. This way, you can access the pointer to a
//particular object using its ID. Depending on what you need, you
//could use other structures than a map
static map<int, A*> objects;
//this is a (non-static) member variable, i.e. unique to each object.
//Its value is determined in the constructor, making use of curID.
int id;
//these are some other member variables, depending on what your object actually is
double x;
double y;
}
Note: The above design is very basic and not complete, but just meant to give you an idea of how to implement what you're asking for using static members/functions. For example, for operations that you want to perform on all the objects, for example, it may be better to implement a static function that iterates through the map of elements, rather than getting the map and then doing the iterations "outside".
Why:
I've never used this method myself, but one potential use case I can think of is e.g. in a graphics or game application, where you may want to only draw objects that are in scope and change certain drawing-related properties of all of them at once, e.g. color or size. I'm working on an application that might eventually need something like this (sort of a visual debugger). I'm sure people can provide more examples in the comments.
Why not:
The picture gets complicated when inheritance is involved.
If you have a class B that derives from A (i.e. B "is an" A), then who should keep track of objects of B? A static member of objects in A, or a similar one in B, or both?
Let's say both. Then what happens if a static function that applies to all objects in A calls a virtual member function on each object? If the virtual function has been overridden in the derived class, then that function will be called instead for all objects being tracked in class A that are actually B objects. What happens if you then call that function again in another static function in B?
There is no way that I know of but you can implement one with static members
#include <iostream>
#include <vector>
class MyClass{
private:
static std::vector<MyClass*> objList;
public:
MyClass() {
objList.push_back(this);
}
static std::vector<MyClass*> getAllObjects(){
return objList;
}
};
std::vector<MyClass*> MyClass::objList;
main(){
MyClass m,a;
for (int i=0;i<MyClass::getAllObjects().size();i++){
std::cout<<MyClass::getAllObjects()[i]<<std::endl;
}
}
No, unless you implement this mechanism yourself. By default it is not provided by C++ language.
You CAN implement this mechanism yourself quite easily - register class in some kind of table within constructor, unregister within destructor. As long as you follow rule of Three, it'll work fine.
Of course there is. Just use Factory pattern to create and destroy all your objects and, in Factory implementation, return a collection of live objects in a Factory function that you will provide.
As has already been stated C++ does not provide a mechanism to do this automatically. However (again has already been stated in the comments) you can use one of the standard library containers to maintain a list of created objects and then register them in the constructor and unregister them in the destructor. The example below shows one way to do this...
#include <iostream>
#include <memory>
#include <utility>
#include <map>
#include <algorithm>
#include <iterator>
#include <typeinfo>
#include <vector>
class Object
{
static std::map<const Object*, Object*> objects_;
public:
Object()
{
objects_.insert(std::make_pair(this, this));
}
virtual ~Object()
{
objects_.erase(this);
}
static std::vector<Object*> get_all()
{
std::vector<Object*> o;
o.reserve(objects_.size());
for (auto obj : objects_)
{
o.push_back(obj.second);
}
return std::move(o);
}
template<class Type>
static std::vector<Type*> get_bytype()
{
std::vector<Type*> o;
for(auto obj : objects_)
{
Type *t = dynamic_cast<Type*>(obj.second);
if (t != nullptr)
{
o.push_back(t);
}
};
return std::move(o);
}
void print() const
{
std::cout << "I'm a " << typeid(*this).name() << " object # " << this << std::endl;
}
};
std::map<const Object*, Object*> Object::objects_;
class Foo : public Object {};
class Bar : public Object {};
int main()
{
std::unique_ptr<Object> o1 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o2 = std::unique_ptr<Object>(new Bar());
std::unique_ptr<Object> o3 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o4 = std::unique_ptr<Object>(new Bar());
std::vector<Object*> objects = Object::get_all();
for (auto o : objects)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Foo*> foos = Object::get_bytype<Foo>();
for (auto o : foos)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Bar*> bars = Object::get_bytype<Bar>();
for (auto o : bars)
{
o->print();
}
}
The above example produces the following output
I'm a class Foo object # 003FED00
I'm a class Bar object # 003FED30
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED90
I'm a class Foo object # 003FED00
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED30
I'm a class Bar object # 003FED90
I need to access a static data member from a destructor, but on program exit it seems that it cannot be guaranteed to still exist! For some reason, the static members are being destroyed whilst there are still outstanding instances of the class. It's odd because I've never heard the advice "Never access static members from a destructor" before, and yet I think I'd know about such a limitation if it existed.
I'll give a concrete example:
class MyClass {
public:
~MyClass() { m_instances.erase(m_name); }
private:
long m_name;
static std::map<long, MyClass*> m_instances;
};
In another class, I tried the following nasty hack which appeared to work, though when I think about it I don't think it's really a solution at all.
class MyClass {
friend class Switch;
public:
~MyClass() { if (m_alive) m_instances.erase(m_name); }
private:
static bool m_alive;
class Switch {
~Switch() { MyClass::m_alive = false; }
};
static Switch m_switch;
long m_name;
static std::map<long, MyClass*> m_instances;
};
What if an instance of MyClass is destroyed after m_instances but before m_switch?? And even if m_switch dies first, the boolean m_alive might have been "destroyed" and therefore possibly overwritten to 'true' (unlikely, I know).
So can anyone offer a better solution? I expect I am missing something very obvious here.
This is clearly a problem of static destruction order. I would recommend something like the following:
class MyClass {
public:
MyClass() { add_instance(m_name, this); };
~MyClass() { erase_instance(m_name); }
private:
long m_name;
static std::map<long, MyClass*>& get_instance_map();
static void add_instance(long aName, MyClass* aObj);
static void erase_instance(long aName);
};
std::map<long, MyClass*>* MyClass::get_instance_map() {
static std::map<long, MyClass*>* p_inst = new std::map<long, MyClass*>();
return p_inst;
};
void MyClass::add_instance(long aName, MyClass* aObj) {
static std::map<long, MyClass*>* p_inst = MyClass::get_instance_map();
p_inst->insert( std::make_pair(aName, aObj) );
};
void MyClass::erase_instance(long aName) {
static std::map<long, MyClass*>* p_inst = MyClass::get_instance_map();
p_inst->erase( aName );
};
If you need the instance map to be deleted, it might not be possible. Otherwise, just use a normal construct-on-first-use idiom. The point here is that the map is a heap-allocated std::map object, and not deleting it just means that it will be flushed away as the OS reclaims the freestore memory which will occur after every other "normal" execution, like a destructor call.
There is no guarantee that static members are destroyed only after all instances of an object of the same class. C++ incorporates no reference counting paradigm (shared_ptr notwithstanding).
When considering lifetime, consider your static members as any other static object. There's really nothing binding them to their containing class other than being in the class's "namespace" (warning: not accurate terminology).
So, if your myClass instances are created statically too, then you need to consider normal static object lifetime rules between them:
Example #1:
#include <iostream>
struct A {
A() { std::cout << "*A "; };
~A() { std::cout << "~A "; };
};
struct B {
B() { std::cout << "*B "; };
~B() { std::cout << "~B "; };
static A a;
};
B t;
A B::a;
int main() {}
// Output: *B *A ~A ~B
As you can see, the static member of B is destroyed before the actual instance of B.
Example #2:
#include <iostream>
struct A {
A() { std::cout << "*A "; };
~A() { std::cout << "~A "; };
};
struct B {
B() { std::cout << "*B "; };
~B() { std::cout << "~B "; };
static A a;
};
A B::a;
B t;
int main() {}
// Output: *A *B ~B ~A
Here the reverse is true. It's a cheap fix for your current issue, but my advice is to avoid static instances altogether; you'll only fall into more static initialisation pitfalls like this down the line... possibly with a future incarnation of the same code!
If you are having these kinds of problems with a static, it must mean that MyClass also has static scope and you can't design code like this with one static accessing the other. It might work and it might not work since you have a problem with the order of destruction.
It's also entirely possible that you have another global (static) causing memory corruption. If this is the case it might mean that overwriting one global might overwrite other near by globals residing in the same memory space, i.e. the static you are having problems with has been corrupted and not deleted.