I have few classes defined in this fashion :
class CSocket {
protected:
int m_SockWorking;
int InitSocket();
void CleanSocket();
}
class CSocketClient : public CSocket {
public:
CSocketClient();
int InitClient();
}
class CApi {
static CSocketClient c1;
public:
// other methods defined
}
Now, in the main routine I create two objects of class CApi. I know that for static member variables there exists only one copy per class. But, how can I access m_SockWorking variable for CSocketClient member variable? Will there be two copies of that non static member variable for the two objects? Can somebody please explain?
All CApi classes will share a single static CSocketClient variable.
m_SockWorking is a protected member of CSocket which is inheirited by CSocketClient this makes it a private variable inside the context of CApi and your application. So you can access it through the use of accessor and mutator functions.
Each CSocketClient has its own m_SockWorking variable. Since all CApi all share the same CSocketClient class, they all share the same m_SockWorking variable.
CSocket.h
class CSocket {
protected:
int m_SockWorking;
int InitSocket();
void CleanSocket();
public:
void setSocket(int val){ m_SockWorking = val; } /* added these functions to show how to accessing m_SockWorking can be done */
int getSocket() const { return m_SockWorking; }
};
class CSocketClient : public CSocket {
public:
CSocketClient();
int InitClient();
};
class CApi {
static CSocketClient c1;
public:
// other methods defined
};
main.cc
#include "CSocket.h"
#include <iostream>
using std::cout;
using std::endl;
int main(){
CApi a, b;
CSocketClient c2;
a.c1.setSocket(0); /* sets static c1 m_SockWorking variable to 0 */
cout << b.c1.getSocket() << endl; /* will print 0 since c1 is a static variable */
c2.setSocket(1); /* set c2 m_SockWorking to 1 */
cout << c2.getSocket() << endl; /* will print 1 */
cout << a.c1.getSocket() << endl; /* will print 0 */
}
Output
0
1
1
Yes, object c1 is unique, so, all data members within to c1 are unique for CApi.
Maybe it's less confusing in this way:
static object c1 is a standalone & unique object for the "CLASS" CApi, accessible by objects of CApi. It belongs to the class, NOT to any objects of CApi; it's NOT A SHARED PART of objects of CApi.
Related
I have a project where I am accessing several classes using a pointer to a parent class. I need to know which child class the pointer is referring to, so I am adding a distinct integer ID number to each of them as a constant class variable.
I need to access this variable using the pointer, so I wrote a getter function for that variable. Since the code for the getter function would be the same for all of the child classes, I tried defining the function in the parent class. This roughly lead to the code found below:
class Parent {
public:
virtual void func();
// Getter function
uint8_t getID() {
return classID;
}
// Set ID to a default value
const uint8_t classID = 0;
};
// One of many child classes
class A: public Parent {
public:
void func() {//do something}
const uint8_t classID = 1;
};
int main(){
Parent* childPointer = new A;
uint8_t currentID = childPointer -> getID();
}
However, running this led to currentID being equal to Parent.classID rather than A.classID.
Making the getID function virtual and definining it in each of the child classes made it work as intended, but this would lead to quite a bit of repeated code. I was wondering if there was a way to define the getter function once in the Parent class, and to make it return the correct value? Otherwise, is there a cleaner way to do it?
In C++ each class has it's own namespace. In your code you have a classID in the Parent namespace and a classID in the A namespace. So every instance of A actually has 2 classIDs. The getID() function only sees the classID in the Parent namespace though. This is why it only returns 0.
A better way would be to define constructors which will initialize the classID in Parent:
#include <cstdint>
class Parent {
public:
Parent(): classID(0){}; //Default Parent initializes with 0
Parent(uint8_t ID): classID(ID){}; //Constructor to be called by children
virtual void func(){};
// Getter function
uint8_t getID() {
return classID;
};
const uint8_t classID;
};
// One of many child classes
class A: public Parent {
public:
A(): Parent(1){}; //Every A calls Parent(uint8_t) constructor
void func() {};//do something
//const uint8_t classID = 1; //This is not needed anymore
};
int main(){
Parent* childPointer = new A;
uint8_t currentID = childPointer -> getID();
}
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.
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.
i have a variable map dataa ehich is used in three different class.i can define this variable globally and put all classes defination in one cpp file but i want to make different files for three different class and thus cant define it globally.
now i want to define this variable in one class say A and then want to use this dataa in the rest two class say B and C.
how can i do this.thanks for anyhelp in advance
You can use public get and set methods to access your variable in class A. Or simply create a public variable in class A.
You can use friends
class A
{
friend class B;
friend class C;
private:
int m_privateMember;
};
class B {
};
class C {
};
Now, B and C can access to A's private members.
But this is not the best way. Try to avoid it.
alternatively you can try to have this variable map data as part of a new singleton class. The rest of your 3 different classes can access this singleton class using get method
file: singleton.h
#include <iostream>
using namespace std;
class singletonClass
{
public:
singletonClass(){};
~singletonClass(){};
//prevent copying and assignment
singletonClass(singletonClass const &);
void operator=(singletonClass const &);
//use this to get instance of this class
static singletonClass* getInstance()
{
if (NULL == m_Singleton) //if this is the first time, new it!
m_Singleton = new singletonClass;
return m_Singleton;
}
int getData()
{
return data;
}
void setData(int input)
{
data = input;
}
private:
static singletonClass* m_Singleton; //ensure a single copy of this pointer
int data;
};
//declare static variable as NULL
singletonClass* singletonClass::m_Singleton = NULL;
File: ClassA.h
class ClassA
{
public:
ClassA(){};
~ClassA(){};
int getVarFromSingleton()
{
m_Singleton = singletonClass::getInstance(); //get a pointer to the singletonClass
return data = m_Singleton->getData(); //get data from singleton class and return this value
}
private:
singletonClass* m_Singleton; //declare a pointer to singletonClass
int data;
};
File: main.cpp
int main()
{
singletonClass* DataInstance;
ClassA a;
int data;
DataInstance = singletonClass::getInstance();
DataInstance->setData(5);
data = a.getVarFromSingleton();
cout << "shared data: " << data << endl;
return 0;
}
Is it possible in c++ to access class variables in other classes without creating an object. I have tried to use static, but the other class doesnt recognize my variable.
I have 3 classes. In two of those the sae variables should be used. In the third class I am changing the values. Would be grateful if you could help. Maybe youve got an example.
class Myclass
{
public:
static int i;
};
int Myclass::i = 10;
class YourClass
{
public:
void doSomething()
{
Myclass::i = 10; //This is how you access static member variables
}
};
int main()
{
YourClass obj;
obj.doSomething();
return 0;
}
static is the right keyword here:
class A {
public:
static int i; // <-- this is a class variable
};
class B {
public:
void f() { A::i = 3; } // <-- this is how you access class variables
};
They only potential problem I can think of is that
You made the class variable protected or private, thus rendering it inaccessible from other code.
You forgot to specify the full scope of the class variable (with A:: in this example).
I think the Singleton Pattern would help, but I'm no big fan of it. A lot better design would be to have one class take ownership of the object, and pass references to this object to the other classes.
yes you can bro, try this
struct car{
string model;
string paint;
int price;
};
int main(){
// creates an object of the class car
car BMW;
// assign the values
bmw.model = "m sports";
bmw.paint ="red";
bmw.price = 24000;
}