Why we have to declare static member function to access private static variable? Why not simply use a public function to access s_nValue? I mean why is it better to use static member function instead of a non-static public function?
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1; // initializer
int main()
{
}
Why we have to declare static member function to access private static variable?
You don't have to:
class Something
{
private:
static int s_nValue;
public:
static int staticAccess() { return s_nValue; }
int Access() { return s_nValue; }
};
int Something::s_nValue = 1; // initializer
int main()
{
Something s;
Something::staticAccess();
s.Access();
return 0;
}
Both methods work as can bee seen here
That being said, it doesn't really make sense to make a non-static member function to access a static variable (as you would need an instance of the class to be able to call it).
If you use pubilc function , you have to call it using an object, and it's not appropriate to call a static function with object, so better to keep it in static method which can be accessible directly through "classname::"
Why we have to declare static member function to access private static variable?
You don't have to. You can access a private static member from any member function, static or otherwise. You can also access it from any friend function, or member function of a friend class.
Why not simply use a public function to access s_nValue?
Because that's less simple than a static function. You need an object to call a non-static member function; why not simply allow access to the static variable without creating an object?
Related
As reported in this Q&A, const static member functions are/were not available in C++. Did anything change since then (2011)?
Is there another way to have static member functions that do not modify the static members of their class?
Something like (pseudo-code):
class C
{
static int a;
public:
static void Incr() { ++a; }
static int Ret() const { return a; }
};
int C::a = 0;
I would need to call a [const] static member function from another class' const member function.
According to the current cppreference.com (page about static members), static member functions still cannot be const, because the const keyword only modifies the this pointer, which static functions obviously do not have.
So nothing seems to have changed since the answer you were referring to was written.
Did anything change since then (2011)?
Nothing changed, you still can't cv-qualify a static member function.
Is there another way to have static member functions that do not modify the static members of their class?
Not a perfect solution, but you may declare const "aliases" to static data members:
static int Ret() {
static constexpr const auto& a = C::a;
// Now C::a is shadowed by the local a
// and the function can't modify it.
// a = 2; // ill-formed
return a * 2; // OK
}
It still requires discipline, but at least that way a compiler can catch unintended modification attempts.
Class which has only static fields and static methods doesn't deserve to be called class. It is just form of functions and global variables with fancy name spacing.
Anyway IMO it is much better to have a regular class with regular fields and methods and then instantiate it as a global variable (not very nice solution, but at least more honest where class contains only static fields and methods).
class C
{
int a;
public:
C() : a(0) {}
void Incr() { ++a; }
int Ret() const { return a; }
};
C instance;
Or use singleton pattern which I hate.
From generated code perspective there should be no difference.
Say I have two functions, and one calls the other to work.
void friendList::addFriend(string userNameIn)
{
if(friendList::isFriend(userNameIn))
//add friend
}
bool friendList::isFriend(string name)
{
//check if user name exists
}
Is this allowed? I am getting errors for:
In member function 'void User::addFriend(std::string)':
and error: cannot call member function 'bool friendList::isFriend(std::string)' without object
Is it because the functions aren't completely filled out yet?
Yes, functions can of course call other functions in C++.
Doing so is not a case of functions being put inside other functions: your question title is misleading.
It looks as if addFriend might be a static member function, and as such it has no object, whereas isFriend is a non-static member function. When a static member function of a class calls a non-static member function, it must supply an object:
class someclass {
// ...
static void static_member();
void nonstatic_member();
};
void some_class::static_member()
{
nonstatic_member(); // error
some_instance.nonstatic_member(); // okay
}
void some_class::nonstatic_member()
{
}
static_member cannot call nonstatic_member, but it can invoke nonstatic_member on an object. It will work provided that some_instance is suitably defined somewhere as an instance of some_class.
The compiler error:
cannot call member function [...] without object
Suggests to me that you are trying to call a non-static member function directly, rather than through an object. For example:
class Foo
{
public:
int DoIt() {}
};
int main()
{
Foo::DoIt();
}
If that's what you're trying to do, you can't. Non-static member functions need to be called through an object:
int main()
{
Foo foo;
foo.DoIt();
}
If you must refrain from calling through an object, then you need to make the member function static:
class Foo
{
public:
static int DoIt() {}
};
int main()
{
Foo::DoIt(); // OK
}
But then, DoIt won't be able to call other non-static member functions.
You want to use the 'this' pointer. this->isFriend(userNameIn)
Code example from http://www.learncpp.com/cpp-tutorial/812-static-member-functions/:
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1;
This code compiles without warnings or errors. I do not understand why.
Shouldn't we get a warning for trying to access s_nValue because it is private? Or these access specifiers do not apply to static members?
The definition of s_nValue is not "accessing" the member from outside the class--it's actually its implementation. Think of this as being just like the actual implementation of a member function, if placed in the source file outside the declaration for the enclosing class.
In other words, access specifiers absolutely apply equally to static members.
That is the definition of the private static member of the class, and therefore it is allowed. Because the definition of static members of class must go outside the class, no matter whether it is private or public.
In short, it is not accessing the member, it is defining it, just like you define private functions outside the class.
Also note: Don't get confused between Assignment and Contructors. The line:
int Something::s_nValue = 1;
Is not "assigning" a value, it's Contructing the object. In general its:
ClassA Something::s_nValue(...parameters...);
C++ allows "assignment" style syntax for Contructors. Example:
class A
{
public:
A(int i) { m_i = i; }
int getI() { return m_i; }
private:
int m_i;
};
class B
{
public:
static int getAI() { return a.getI(); }
private:
static A a;
};
A B::a = 2;
this code compiles and runs without errors:
class foo{
static foo *ref;
foo(){}
public:
static foo *getRef(){
return ref;
}
void bar(){}
};
foo* foo::ref = new foo; // the construcrtor is private!
int main(int argc, const char *argv[])
{
foo* f = foo::getRef();
f->bar();
return 0;
}
could somebody explain why can the constructor be called?
That scope isn't global - static members are at class scope, and so their initialization expression is also at class scope.
The answer is that it is not available in the global scope. The initializer of a static member is defined to be inside the class scope, so it has access to the private members.
ยง9.4.2/2 [...]The initializer expression in the definition of a static data member is in the scope of its class (3.3.6).
This form of initialization of static members are not necessary in older c++. They are made compulsary in later release of c++.
And, this form of static member initialization will generally used to initialize the static members before creation of any class objects.
(E.g) int MyClass::objectsCounter=0;
But by,
foo* foo::ref = new foo;
this statement you are just initializing a static member (which is of pointer type) by creating a new object.
And in this case you are intializing a private member by calling a private method of its own class.
Hence there is no role of globe scope here.
static function in c++
SO, there can be only one instance of static function for this class. Right?
In C++, a static member function is just like a normal, global function, except with respect to visibility of names:
The name of the function is qualified with the class name.
Like a friend function, a static member function has access to private and protected class members. Also like a friend function, however, it does not have a this pointer, so it only has access to those parts of objects to which you've given it access (e.g., passed as a parameter).
(Thanks Alf): You can't declare any member function (static or otherwise) as extern "C".
A static member function (inside a class) means that you can call that function without creating an instance of the class first. This also means that the function cannot access any non-static data members (since there is no instance to grab the data from).
e.g.
class TestClass
{
public:
TestClass() {memberX_ = 10;}
~TestClass();
// This function can use staticX_ but not memberX_
static void staticFunction();
// This function can use both staticX_ and memberX_
void memberFunction();
private:
int memberX_;
static int staticX_;
};
Making a function static allows it to be called without instantiating an instance of the class it belongs to. learncpp.com has some more on the subject and check out the following example which will fail to compile:
class Foo
{
public:
static void Bar1();
void Bar2();
};
int main(int argc, char* argv[])
{
Foo::Bar1();
Foo x;
x.Bar2();
Foo::Bar2(); // <-- error C2352: 'Foo::Bar2' : illegal call of non-static member function
return 0;
}
Static functions can be called without actually creating a variable of that type, e.g.:
class Foo
{
public:
static void Bar();
void SNAFU();
};
int main( void )
{
Foo::Bar(); /* Not necessary to create an instance of Foo in order to use Bar. */
Foo x;
x.SNAFU(); /* Necessary to create an instance of Foo in order to use SNAFU. */
}