#include <iostream>
using namespace std;
class MyClass
{
private:
static int x;
static int calc(int a, int b)
{
cout << "chekcing !! ";
return b * a;
}
};
int MyClass::x = 1;
int main()
{
MyClass::calc(1,2);
MyClass::x += 3;
return 0 ;
}
Question : As far i know Static members are not a part of class , then why do we have a check of access specifier ?
Each static member is shared across all the instances of that class. So they don't belong to one particular class instance but they belong to the class itself.
Access specification rules are per class not per object
From above, it is logical that the access specification rules apply to static members.
Your confusion stems from the fact that if you check size of a class with static member there is no overhead dues to the presence of the static member. This behavior is correct. The static members do not contribute towards the size of the class but they are still a part of the class and the standard explicitly says so.
Reference:
9.4.2 Static data members:
§1:
A static data member is not part of the subobjects of a class. If a static data member is declared thread_local there is one copy of the member per thread. If a static data member is not declared thread_local there is one copy of the data member that is shared by all the objects of the class.
Related
If I have nested classes, and these nested classes have static members, will those members still be static for the enclosing class? For example, if I have
class Enclosing {
public:
Enclosing();
private:
class Nested {
public:
Nested();
private:
static int thing;
};
};
If I do
auto A = Enclosing();
auto B = Enclosing();
Will A and B be able to have different values for thing?
Will A and B be able to have different values for thing?
No they won't have different values. All instances will see the same value for thing; the nesting of the class has no impact here.
static member variables are "associated with the class" (i.e. over non-static members that are associated with the instances of the class). From cppreference;
Static data members are not associated with any object. They exist even if no objects of the class have been defined. If the static member is declared thread_local (since C++11), there is one such object per thread. Otherwise, there is only one instance of the static data member in the entire program, with static storage duration.
Live sample.
My lecturer asked a question that I can't find its satisfactory answer. Quote from him " Just tell me a sentence why cannot static functions(methods) access to non-static data members? " Could you tell me why? I want to learn.
static method can be called on the class itself, no instance of that class is necessary.
This means that there is no instance of the class and so non-static data members have not been created and initialized.
You can call static methods using the syntax ClassName::MethodName().
In this case you are not accessing an concrete object and hence you can not
access non-static members.
Consider the following code:
class C {
public:
C(int i) { _i = i; }
int getI() { return _i; } // ok
/* error: using non-static member in a static method */
static int sgetI() { return _i; }
private:
int _i;
};
int main(void) {
C c1(1);
C c2(2);
int n1 = c1.getI(); // ok, n1 = 1
int n2 = c2.getI(); // ok, n2 = 2
int n3 = C::sgetI(); // what? does not make sense!
}
static-method and static-members are common among the all the instances of class.
So when you try to access non-static data-members the compiler can't decide what is the memory address of that non-static data-member. Remember, class is just a template, while object is one who has the address and stores the data in that particular format defined in class.
Let's take an example :
for the sake of argument let's assume C++ static method allows us to access non-static data-members. Let's create a class named person with name as string data member and two methods get_name() and put_name()
class person
{
string name;
public :
void get_name(){cin >> name;}
static void put_name(){cout << name << "\n";}
};
Now writing the driver program...
int main()
{
person p1,p2;
p1.get_name(); // input : alice
p2.get_name(); // input : bob
person :: put_name();
return 0;
}
We can clearly observe after taking two names as inputs, when we call put_name() what output the compiler would give? alice, bob or NULL ? because static member function is not affiliated with any of object it can't decide what to give as an output.
So now maybe it is clear that why cannot static functions(methods) access to non-static data members?. If you got your answer hope you appreciate the effort.
What are the major differences between the static class member variable and the static variable ?
Both static class members and static varibles are accessed from member functions of any class. What are the specific uses of static class members and static varibles?
The only reason is code cleanliness. You cannot restrict access to a global static variable like
static int globalValue=5;
it is (at least) visible in the source file you defined it.
With a class static, you can give a user of your class hints, how you wish to access it or be accessed. It is only visible within the class scope:
class myGlobalContainer
{
public:
static int myInt;
protected:
static float myFloat;
private:
static bool myBool;
};
the access of myInt is done by:
int x=myGlobalContainer::myInt;
the public modifier gives the user the hint that you see this value as part of the myGlobalContainer and wish him to use it. You do not polute the global namespace like you do with the globalValue.
The modifier protected and private shows that you do not wish that an "outsider" access those values.
protected and private static attributes are mostly used to share information between the instances of a class, for e.g. a instance counter:
class myGlobalContainer
{
public:
myGlobalContainer()
{
if(counter==0)
DoSomeSpecialGlobalInit();
counter++;
}
~myGlobalContainer()
{
counter--;
if(counter==0)
DoSomeSpecialGlobalUnInit();
}
private:
static int counter=0;
};
public static attributes are often seen with const. They mostly give a user a shortcut. For e.g.:
COLOR white=COLOR::WHITE;
instead of:
COLOR white=COLOR::FromAGBR(255,255,255,255);
Add least:
If you should use statics or not is a complete other discussion.
Both static class members and static varibles are accessed from member
functions of any class.
That is not true:
class A {
private:
static int x;
};
int A::x = 5;
class B {
static int y;
public:
void do_something()
{
std::cout << A::x; // Can't access A::x because it's private
}
};
int B::y = 10;
Although, if we did this:
static int J = 9;
class A {
private:
static int x;
};
int A::x = 5;
class B {
static int y;
public:
void do_something()
{
std::cout << J; // Yes, J is global.
}
};
int B::y = 10;
Static member variables can access the private section of it's class opposed to a normal static variable.
Static member variables may not be defined inside the class body, unless it's const static or constexpr static.
Static member variables may be used as default arguments for the member functions in their class. Opposed to normal static variables, unless they are global.
Uses: if you want a variable to be alive until the end of your program in both cases but static member variables have access to the private section of that class.
We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.
If you declare a static member public then you can access it without member functions as well.. Static has nothing to do with the scope of variable.. It specifies the storage duration only..
A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present.
My list of differences:
You can make static class member protected or private.
You can't make static class member global.
Can't think of anything else.
Static class members are used to share data between different instances of a class. The storage for these members is allocated only once and it is only this instance of the static member that will be available for all objects of the class.
Static variables inside a function are variables that retain its value through function calls.
A classic but simple example of this is a int type static counter in a function where you want to keep track of the number of times this function was called. Since this retains its value through calls, you can increment it inside the function every time it is called.
#include "B.h"
class A
{
public :
A()
{
s_b = new B();
b = new B();
}
static B *s_b;
B *b;
};
#include<iostream>
using namespace std;
#include "A.h"
int main()
{
cout<<"hello";
}
In my project I have seen static object as above. But not able to know what is the exact use of it and how they are different from general object.
Please help me in finding out what I can do with s_b which is not being done by b.
For one, s_b doesn't take up memory for each instance of A that is created, whereas b does. The sizeof(A) is increased by b, but not by s_b.
A static is shared between all instances of the class, so it acts like a global. You don't need an object to access it, you can use A::s_b directly.
The only real difference between a static member and an object or function defined at namespace scope is access. A static data member can be private, for example, in which case it cannot be accessed outside of the class; and a static function member can access private data members, which a function at namespace scope cannot.
The access syntax is also different: if outside the class, you must use ClassName::memberName (or classInstance.memberName) to access the member. There is no using which can make it accessable otherwise.
generally speaking static members have to be initialized outside the declaration of the class except for constant int type if you are not using C++11.
So your code posted above is flawed. you need a statement like
A::s_b = B();
outside the class A { ... }; To initialize an static member inside an non static constructor is wrong because the constructor is used to construct an object but the static member
does not belong to the object but belong to the class. So these static members can not be modified through static member functions.
Think "class" as "human being" and an object of that "class" as a specific person, like "John Smith". So if you have a field, "salary". That should be a non-static field since each person has a different salary. But if you have field, "total_population", which should be a static member because this field semantically does not belong to one specific person but to the whole "human being".
I see some usage of internal struct in c++ function.
There is a common interface IBase. Here is the draft code.
class IBase
{
virtual Method()=0;
}
vector<IBase*> baseList;
Then a function defined an internal class based on that IBase, and then push the internal class object into the baseList.
void func()
{
struct Object : public IBase
{
virtual Method()
{
// Method of Object in func
}
}
IBase* base = new Object();
baseList->push(base);
}
It seems a strange usage, but a nice implementation of message/event creation pattern.
Other threads maybe use this baseList to handle the incoming event.
What's the scope of internal struct of "struct Object"? It's very interesting. Is there some documents talking about this?
What's the scope of internal struct of "struct Object"?
The scope of the local classes is the function in which they're defined.But that isn't interesting in itself.
What makes local classes interesting is that if they implement some interface (like your code does), then you can create instances of it (using new) and return them (for example, as std::vector<IBase*>), thereby making the implementation accessible through the base class pointer even outside the function.
Some other facts about local classes:
They cannot define static member variables.
They cannot access nonstatic "automatic" local variables of the enclosing function. But they can access the static variables.
They can be used in template functions.
If they are defined inside a template function, then they can use the template parameters of the enclosing function.
Local classes are final, that means users outside the function cannot derive from local class to function. Without local classes, you'd have to add an unnamed namespace in separate translation unit.
Local classes are used to create trampoline functions usually known as thunks.
EDIT
Some references from the Standard (2003)
9.8 Local class declarations [class.local]
\1. A class can be defined within a function definition; such a class is
called a local class. The name of a
local class is local to its enclosing
scope. The local class is in the scope
of the enclosing scope, and has the
same access to names outside the
function as does the enclosing
function. Declarations in a local
class can use only type names, static
variables, extern variables and
functions, and enumerators from the
enclosing scope.
[Example:
int x;
void f()
{
static int s ;
int x;
extern int g();
struct local {
int g() { return x; } // error: x is auto
int h() { return s; } // OK
int k() { return ::x; } // OK
int l() { return g(); } // OK
};
// ...
}
local* p = 0; // error: local not in scope
—end example]
\2. An enclosing function has no special access to members of the local
class; it obeys the usual access rules
(clause 11). Member functions of a
local class shall be defined within
their class definition, if they are
defined at all.
\3. If class X is a local class a nested class Y may be declared in
class X and later defined in the
definition of class X or be later
defined in the same scope as the
definition of class X. A class nested
within a local class is a local class.
\4. A local class shall not have static data members.
\4. A local class shall not have static data members.
BUT you can do this, inside of a local class
int GetCount()
{
class _local
{
public:
static int Count(int count = std::numeric_limits<int>::max())
{
static int count_ = 0;
if (count != std::numeric_limits<int>::max()) count_ = count;
return count_;
}
static float Operation(float a, float b)
{
_local::Count(_local::Count() + 1);
return a;
}
};
_local::Count(0);
CALLBACK( _local::Operation);
return _local::Count();
}
_local::Count can be used to read and write the otherwise static variable
-aydin
This is normal C++. The scope of struct Object is only the function func. However, you can still use objects of this type without knowing which concrete type they are, since they inherit from IBase. This is used to encapsulate implementation.
A very interesting use of a local class is presented by Jason Turner in his CppCon talk focused on programming of Commodore 64 game in C++17. He shows how to use the RAII principle on the function level.
He basically establishes invariants in the constructor of a local class in a function returning an instance of this class. The invariants duration is thusly controlled by the lifetime of the returned object. It is quite similar to what RAII wrappers like std::lock do, just slightly different.
You can see the appropriate part here, but I love his performance and recommend to see it all the way through.