Reaching static variables in C++ - c++

If I define a static variable in classA:
static int m_val;
and initialize like
int classA::m_val = 0;
Can I use directly m_val as it is in order to access it in ClassA (or any other class) or should I use it like classA::m_val.

Inside of ClassA, just write m_val. Outside of ClassA, ClassA::m_val.
However, m_val is not const in your example, so it (typically) should be private anyway. In that case, you'd not access it directly from other classes but provide a member function to retrieve a copy:
class ClassA
{
private:
static int m_val;
// ...
public:
static int GetVal();
};
Implementation:
int ClassA::m_val = 0;
int ClassA::GetVal()
{
return m_val;
}

Related

Dont allow access to member variable directly within same class

I am not sure is my question is right or not? But let me still try to ask once.
I have a Class with have few member variables defined. As per OO concepts, every member function can access , all member variables of its class.
But I want these member variable to be accessed via specific methods (Lets say Getters) , even within same class member functions.
It there any way to do it?
class A {
public:
void func1();
void func2();
B getB();
private:
B b;
}
void A::func1() {
b.functionFromB(); // function uses member variable b directly
}
void A::func2() {
B b1=getB(); // function ask for B from a function and then uses it. // I need something like this... And ensure each function uses same way otherwise there should be warning...
b1.functionFromB();
}
Thanks,
Kailas
No, there is not. You can do it via encapsulation and inheritance like:
class shape
{
private:
int angles;
protected:
shape(int angles_):angles(angles_){};
int getAngles() const;
}
class square : private shape
{
public:
square():shape(4){}
void doSth()
{
\\ you can access angles only via getAngles();
}
}
Any private members of the class can be accessed from within the class, but not by users of the class. So it looks like you need private members and public methods that allow access to them.
class A
{
private:
int a;
public:
int getA() {return a;}
};
int main()
{
A inst;
int t;
inst.a =5; // error member a is private
t = inst.getA(); //OK
}
The concept extends fine to nested class declarations in case you only want to allow instance of a class to be created from another class; details here
As others have said - you have to add an additional layer.
If you want to give access to specific methods then you can use the friend keyword. E.g.
// Public.h
#pragma once
class Public
{
public:
Public();
int GetI() const;
float GetF() const;
private:
std::unique_ptr<Private> p_;
};
//Public.cpp
#include "Public.h"
Public::Public()
: p_(new Private)
{
}
int Public::GetI() const
{
return p_->i_;
}
float Public::GetF() const
{
return p_->f_;
}
// Private.h
#pragma once
class Private
{
friend int Public::GetI() const;
friend float Public::GetF() const;
int i_;
float f_;
};
Keep in mind that every friend method can access ALL private members.
If you really really want to limit which methods can access which members then you can wrap each member in a separate class/struct and make only the getter/setter of that member a friend of that class/struct but I would not recommend this approach.

Calling a function from one class in another class

If I have these two sets of .cpp and .h files set up like this and I l want to put an add() function in a.cpp that adds ten integers and returns sum. Then I have class b that will return the average but I want to use the sum of the ten integers that I got from class a. How can I call function add() in function average() so it can return the sum? I don't know if this is getting my question across well, I just made this example up to try it illustrate it.
class a {
private:
int a[10];
public:
a( );
int add( int);
};
class b {
private:
int d;
public:
int average(int );
}
You can call member functions on an object of a class, not on the class itself. Creating an object is almost as creating a variable, for example a my_a;. Then you can use the add member function of the my_a object as my_a.add(42).
If you do not need objects (but do need classes for some reason), use static member functions and variables as follows.
class MyClass {
private:
static int variable;
public:
static int accessor() { return variable; }
};
In this case, you can call the static member function without creating an instance as MyClass::accessor().
class A {
public:
static int add(int);
};
class B {
public:
void average(int val){
A::add(val);
// Some logic
}
};

Private static class members

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.

Access static const in another class.

A static const variable declared and defined in a class. How to access it in the private access of another class in same project. Is it possible?
//in some header file
Class A{
public:
//some data
private:
static const uint8_t AVar =1;
//other data
};
//in some another header file
Class B{
static const Bvar;
};
//here inside Class B it possible to give Bvar = AVar ? If yes, How ?
A clean way to avoid duplication of the magic value without weakening encapsulation of either class is to move the magic value to a different place that is publicly accessible to both classes.
For example:
namespace detail {
enum MAGIC_NUMBER_T {
MAGIC_NUMBER = 1
};
}
class A{
private:
static const uint8_t AVar = detail::MAGIC_NUMBER;
};
class B{
static const uint8_t BVar = detail::MAGIC_NUMBER;
};

Member function called only on initialization of first instance of a class (C++)

I have a member function for a base class that I only want to be called [once] on the initialization of the first instance of the class (whether it be a direct instance of the base class, or an inherited class). Basically, I want to avoid unnecessary function calls.
A thing that is done only done during the first time something happens is the initialization of function local statics during the first execution of the surrounding function. So how you could do it:
class X {
static int firstInitFunc();
public:
X() {
static int onFirstCtorCall = firstInitFunc();
}
};
Now the first time you create an X, onFirstCtorCall will be initialized (threadsafe), calling the function. Any following creation of X won't call that function again.
If you have multiple constructors on X, you'll still want only one call to the function. You can achieve that by either delegating to the constructor with the static variable or by using another static function:
C++11:
class X {
static int firstInitFunc();
public:
X() {
static auto onFirstCtorCall = firstInitFunc();
}
X(int) : X() // delegate to X()
{ /* ... */ }
};
C++03:
class X {
static int firstInitFunc();
static void callFirstInit() {
static int onFirstCtorCall = firstInitFunc();
}
public:
X() {
callFirstInit();
}
X(int) {
callFirstInit();
}
};
Update: I'll pick up juanchopanza's comment and provide an example using std::call_once:
C++11 using call_once
class X {
static void firstInitFunc(); //see note to return types
static std::once_flag firstInitFlag;
public:
X() {
std::call_once(firstInitFlag, firstInitFunc);
}
X(int) {
std::call_once(firstInitFlag, firstInitFunc);
}
};
Note to return types: While in the case of function local statics' initialization used for the function call, that function must return a value, with wich the static will be initialized. In contrast, with std::call_once the function may not have a return type, because any returned value will not be evaluated.
Simple solution:
class C
{
private:
static bool runOnce;
public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};
bool C::runOnce = false;