How do I access a static member in a class with all static methods?
I want to have a group of related functions but also have some important data members initialized before any of these functions are called. I thought a class with only static members would be the way to go. Compiler in VS2008 doesn't like me trying to access "a".
Surely I'm missing something small but still very confused. :P
(Even without the invalid access of "a" the constructor isn't called when calling testMethod() from main.
class IPAddressResolver
{
private:
public:
static int a;
IPAddressResolver();
static void TestMethod();
};
IPAddressResolver::IPAddressResolver()
{
IPAddressResolver::a = 0;
cout << "Creating IPAddressResolver" << endl;
}
void IPAddressResolver::TestMethod()
{
cout << "testMethod" << endl;
}
You need to define your static data member outside of the function, like
class IPAddressResolver
{
private:
static int a;
IPAddressResolver();
public:
static void TestMethod();
};
int IPAddressResolver::a = 0;
void IPAddressResolver::TestMethod()
{
cout << "testMethod" << endl;
}
Your constructor is not called, since you don't create a new instance of the class. For a static utility class, you don't need instances, so you can omit the constructor altogether. Alternatively, you might want to declare it private to make it explicit that the class shall not be instantiated (see above).
Notes:
it is not recommended to use public fields in classes, so I turned a into private,
static utility classes are usually stateless, so if you need to have fields within your class, this maybe a sign that the class would better be a Singleton.
Somewhere outside of the class definition, you need to define and initialize your static data members associated with that class.
Easiest is just to put
int IPAddressResolver::a = 0;
in your IPAddressResolver.cpp file.
I want to have a group of related functions but also have some important data members initialized before any of these functions are called
Sounds to me like you want a Singleton, not a class with only static members.
Related
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.
Suppose I have class B which gets a value 'v' in the constructor from another class A. How can I read this value from class C?
Class C will be instantiated on demand, but A has created B and passed the 'v' already. 'v' will change in every instantiation. I have tried to make 'v' static in Class B. Would it work? I could not implement it properly.
Class A {
public:
int* v;
B b1;
A(int* var) : v(var), b1(var) {};
}
How to access the same version of 'v' from a C class?
I can define B and C however I like in order to achieve the goal. But I cannot change A for that purpose.
You need a (public) static member
class A { //let's stick with your naming convention!
public:
static int a;
}
A::a = 4;
However allowing people to change A::a means that your program will probably end up relying on a global unencapsulated state... which is usually a sign of a bad design.
If you member was const however you are really relating a constant to your class, which is not so bad.
class A {
public:
static const int a = 4;
}
std::cout << "A:a is always " << A::a << std::endl;
EDIT BASED ON UPDATED QUESTION
If you require help with building a class I would recommend that you use a factory of some kind. If I understand your requirement you want to be able to inject a value into every class A and class B instance. This value "v" is based on a Class C.
So...
class C {
private:
// up to you where you implement the getUniqueNumberForNow function
// (global free function for example)
static const int v = getUniqueNumberForNow();
public:
static A createA(){
return A(v);
}
static B createB(){
return B(v);
}
}
The getUniqueNumberForNow() function just gets whatever your value should be. It will be then stored in class C and can be used during the creation of A an\or B. Now just make A and B's CTORs private and make C a friend of both and you will have only one way to create an A or B, and it will always use the correct value.
See NeilMonday's link in the comments below for info on friend classes.
Last thing is if you want to have the value change for every instantiation of A you can just do this in the factory:
static A createA(){
return A(getUniqueNumberForNow());
}
However if that is really what you want then just do this:
class A {
public:
A() : val (getUniqueNumberForNow()), b(B(val)){}
}
You cannot access a 'v' which has never passed to the class. Instead you can make a static copy of it as a member in your class A. It will update every time A is instantiated like this:
Class A {
public:
int* v;
static int* staticv;
...// Constructor etc
}
in your .cc code of A:
int* A::staticv;
...
A::staticv=this->v;
now any class can access to this value by:
A::staticv;
I have an abstract base class called Base that other programmers are to write implementations for. In some other part of the application, I want to catch all implementations that have been written and construct a single instance of each. If this could be done with no additional instructions to others beyond "implement Base", that would be beautiful. However, the code I have below, requires that each implementation register itself. It also doesn't work.
#include <iostream>
#include <vector>
class Base;
std::vector<Base*>* registrationList = new std::vector<Base*>;
class Base {
public:
Base(){}
virtual void execute() = 0;
};
class ImplementationOne: public Base {
public:
ImplementationOne(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation One." << std::endl;}
static int ID;
};
class ImplementationTwo: public Base {
public:
ImplementationTwo(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation Two." << std::endl;}
static int ID;
};
int main(int argc, const char * argv[]){
std::cout << "Registration List size: " << registrationList->size() << std::endl;
for(auto it = registrationList->begin() ; it != registrationList->end() ; ++it){
(dynamic_cast<Base*>(*it))->execute();
}
return 0;
}
I get an output of: Registration List size: 0, so it is clear that the implementations were never instantiated. It is probably obvious that this wouldn't happen, but I am a beginner and this is the best I could come up with. I assumed that static int ID; would force instantiation of each implementation, which would then register themselves. I can see static does not result in instantiation. I leave it in my code here since it shows my intent.
What can I do to get automatic instantiation of each implementation? Is it possible?
Adding static members does not cause an instance to be generated, it merely declares that this type has a "global" variable. You never actually defined these members though, so if you tried to use them for anything you would have had a linker error. You'll have to actually instantiate an object and register that.
One solution might be to simply require each derived type to register an instance at startup. This is actually quite easily done, as I show here. (Note I moved your global to a static local of a static function. This prevents several problems you haven't run into yet, including providing an "owner" for the global.)
Unrelated to your issue, your code has problems:
There is almost never any reason to have a pointer to a container.
You are deriving polymorphically from a type with no virtual destructor.
You dynamic_cast<Base*> for no apperent reason.
Each of your derived classes declares but does not define a ID member.
Of course the vector is empty, you never add anything to the it. The constructors of the derived classes are not called since you never create any object instances of them.
Just because you have static members doesn't mean any object instances will be created. It just guarantees that value will be the same between different instances.
You have to explicitly create instances of the classes to have the constructor being called.
How can I access a variable that has been declared as static and protected in a class definition for use in another file b.cpp
The only code allowed to use protected class members (static or not) are explicit friends of the class in question and classes derived from the class in question (and of course, members of the class itself). Therefore, if "you" want to access that value, then "you" must either be a friend of that class or a member of a class derived from it.
The protection classes (public, protected, and private) exist to provide protection for data. By declaring the member to be protected, the writer of that class is making a semi-strong statement about what code should be allowed to touch that piece of memory. If you're not a derived class or have been given permission with an explicit friend specification, then you're not allowed to touch it.
You should not derive from a class solely to get access to a protected static member. You should only derive from a class if it makes sense to do so based on what your derived class is trying to do.
Having declared as protected, the static variable can only be accessed with in it's member functions and it's derived classes( public, protected inheritance ).
I faced this once in a class that I can't modify(standard adaptors), and came up with the following solution with the help of SO & Google!
#include <iostream>
class my_type{
protected:
static int var;
};
int my_type::var = 0;
int& get_var(my_type& obj){
class protected_accessor : my_type{
public:
static int& get_var(my_type&){
return my_type::var;
}
};
return protected_accessor::get_var(obj);
}
int main(){
my_type obj;
std::cout << get_var(obj) << std::endl;
get_var(obj) = 1;
std::cout << get_var(obj);
}
I have used a variation of this code in my tiny utility: https://bitbucket.org/AraK/streamer/wiki/Developer_FAQ. Look for "Streaming Standard Adapters".
I want to know why cant we create object if the constructor is in private section. I know that if i make a method static i can call that method using
<classname> :: <methodname(...)>;
But why can't we create object is what I don't understand.
I also know if my method is not static then also I can call function by the following:
class A
{
A();
public:
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj =(A*)malloc(sizeof(A));
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}
So, my question is: why can't we create an object when constructor is private?
Because it is not accessible to the program, that's what private means. If you declared a member function or variable private, you would not be able to access them either. Creating private constructors is actually a useful technique in C++, as it allows you to say that only specific classes can create instances of the type. For example:
class A {
A() {} // private ctor
friend class B;
};
class B {
public:
A * MakeA() {
return new A;
}
};
Only B can create A objects - this is useful when implementing the factory pattern.
A constructor is a special member function. It obeys the same rules as any other method when it comes to accessing it. The private access label prevents class users from invoking/accessing members declared under it.
The "new" operator needs to call the constructor, so if the constructor is private you can not execute the code "obj = new A" except inside member functions of the class A itself.
I would guess that what you have encountered is a technique that is very often used in Java (and yes I know you're writing C++, but the principle is the same) where the designer of the class wants to make sure that one and only one instance of this class will ever exist (which is called a "singleton"). To achieve this, he needs to prevent other code from creating further instances of the class using new, and making the constructor private is one way to do that. Here's a piece of Java code illustrating the technique.
public class MySingleton {
private MySingleton() {
// Private constructor, to prevent instantiation using "new"
// outside of this class.
}
public synchronized static MySingleton getInstance() {
static MySingleton instance = null;
if (instance == null) {
// I can use new here because I'm inside the class.
instance = new MySingleton();
}
return instance;
}
}
Even if you don't know Java, the syntax is similar enough to C++ that you should understand what this code is doing. The point is that the only way to get a reference to an instance of the MySingleton class elsewhere in the code is to call the static class member getInstance().
MySingleton obj = MySingleton.getInstance();
You can't instantiate your class because the constructor is private. private member variables and functions cannot be used outside of the class itself.
If you want to be able to instantiate your class, you have two options.
Option 1 is to make the constructor. This is the Right Thing to do in the vast majority of cases. Making a constructor private is a useful technique, but only when trying to accomplish specific goals.
Option 2 is to create a public static factory method. You would typically do this when Option 1 isn't an option.
class A
{
A();
public:
static A* Create() { return new A; }
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj = A::Create();
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}