Static Functions and class variables? - c++

I have broken down my issue into a small simple program.
I have a class myclass I have created in a separate .cpp file "classes.cpp" and declared in the header file "classes.h". myclass contains a variable a of which is initialized when instantiated. This makes variable a = 5.
My overall goal is to create a class in a separate .cpp file declared in a .h file which I can create multiple instances of in my main() program. The problem I am having is this.
In my main() function I create an instance of myclass called first.
my main program shows the variable a is set to the number 5.
If I want to change that number using a static function (and it has to be a static function as this relates to something much bigger in another program I am writing). I call the static function directly and in that static_function I create an instance of myclass and call the non_static_function because static functions have no implicit 'this' connecting them to an object.
In my non_static_function I change the value to the number 8. The problem is that the value of variable 'a' in 'first' remains at 5 when I want it to be 8. I need to change the value using first->static_function(8) and not by first->a = 8. . How can I do this?
Code below:
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "the actual value of a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass::myclass()
{
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}
void myclass::static_function(int x)
{
myclass *p = new myclass();
p->non_static_function(x);
}

If you want every instance of myclass to have its own a and you want to call a static function to change it then you need to pass the instance you want changed to the static function. A static function can only modify static members of a class or the members of an instance that is inside its scope. Non static member functions can change any variable that is a member of the class.
class Foo
{
private:
int bar;
public:
static void static_function(int value, Foo & foo) { foo.bar = value; }
void non_static_function(int value) { bar = value; }
};
int main()
{
Foo foo;
Foo::static_function(8, foo);
// now bar will have the value of 8
foo.non_static_function(20);
// now bar will have the value of 20
}

I have finally found a way to deal with this small problem. Above the 'myclass' definition in classes.cpp I declare a 'myclass' variable
myclass *tgt; . Then in my constructor for 'myclass' I just allocate the instantiated object to a my global myclass variable of which I can access from the myclass definition tgt = this; Now I can use tgt in my static function to call the non_static_function in my 'myclass' definition and it all works perfectly.
NathanOliver, you are correct in saying that I need a class instance but the way I have done it here suits my needs. Passing the instance of myclass is certainly another way of doing this but it would require a global function above my 'myclass' definition.
Thanks for the help.
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->non_static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;
myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass *tgt; // *Add a global myclass variable above the myclass
definition*
myclass::myclass()
{
tgt = this; // *In the constructor allocate the instantiated class
//from main() to "tgt" .*
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
// Now see that the value of a is changed.
cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
}
void myclass::static_function(int x)
{
tgt->non_static_function(x);
}

Related

How to access data type of a class declared in one class into another class (both in different translation unit)?

I have 5 files. (1. A.hpp, A.cpp : 2. B.hpp, B.cpp : 3 main.cpp)
// A.hpp
#ifndef MY_CLASS_A
#define MY_CLASS_A
#include <iostream>
class B; // forward declaration so that I could do B * b;
struct s {
int x;
double y;
};
class A{
s my_struct;
int size;
B * b;
public:
A(int, double, int);
void f1(s);
void f2(); // this function calls B's f1 function
s get_struct();
int get_size();
void print();
};
#endif
Then I have its implementation as
// A.cpp
#include "A.hpp"
#include "B.hpp"
A::A(int x_, double y_, int size_):my_struct({x_, y_}), size(size_){}
void A::f1(s s_){
// do stuff
s_.x = 5;
s_.y = 51.99;
}
void A::f2(){
int val;
// Here I am calling B's f1 function
val = b->f1(my_struct);
}
s A::get_struct(){
return my_struct;
}
int A::get_size(){
return size;
}
void A::print(){
std::cout << " ----- " << std::endl;
std::cout << "x = " << my_struct.x << std::endl;
std::cout << "y = " << my_struct.y << std::endl;
std::cout << "size = " << size << std::endl;
std::cout << " ----- " << std::endl;
}
Then I have B
//B.hpp
#ifndef MY_CLASS_B
#define MY_CASS_B
#include "A.hpp" // I placed here A.hpp because I am
// trying to use A's struct type
class A;
class B{
public:
int f1(s); // A's struct use here to get struct by value
};
#endif
and its implementation as
// B.cpp
#include "B.hpp"
// used A's struct here again
int B::f1(s my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
finally main as
// main.cpp
// As per comment I should place #include "A.hpp" here
#include "A.cpp"
int main(){
A a(4,9.9, 5);
a.print();
return 0;
}
My main question is how can I access the struct declared in class A into class B?
I have tried to use forward declaration by failed miserably.
Open your C++ book to the chapter on pointers and references, and read that chapter again.
"The struct declared in class A" is my_struct, which is a private class member.
To have it accessible elsewhere, you need to pass it by reference.
int B::f1(const s &my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
Now, when you invoke this from A:
val = b->f1(my_struct);
This will now pass a reference to the my_struct member, instead of making a copy of it.
Note that the parameter is declared as a reference to a const instance of s, because f1() does not need to modify it. If it does, simply pass it as a non-const reference:
int B::f1(s &my_struct){
Now, f1() will be able to modify my_struct, and end up modifying this private instance of A's class, that was passed to it.
P.S. This has nothing to do with different translation units. Whether this whole thing is in one translation unit, or is split across half a dozen of them, classes and references work the same way.

Accessing struct and union member functions within a class

In this program I just want to test a structure and union within a class itself.
I had created a public struct, and declared a union within it.
I am using Visual Studio and Qt Creator to type this code.
I want to ask, is defining a struct within a class good and accessible?
I am having problem with that.
If this is correct, how could I access the method or data member of the struct from main?
I'd also like to use the union member of the struct.
If the method or functions of the struct are not accessible this way,. what's another way of doing it?
//************************************************************************************
#ifndef CTEST_H
#define CTEST_H
class CTest {
int value;
public:
CTest(int);
int getValue();
struct CTESTSTRUCT {
union CTESTUNION
{
enum CTestEnum {
var1 = 1
};
char varChar1 = 'Y';
char varChar2 /*= 'N'*/; //union atmost have one field initializer
};
int structValue();
int testVal;
};
~CTest();
};
#endif
//************************************************************************************
#include <iostream>
#include "CTest.h"
CTest::CTest(int argVal) : value(argVal) {
std::cout << "Constructor Called" << std::endl;
}
int CTest::getValue() {
std::cout << "getValue Called" << std::endl;
return value;
}
int CTest::CTESTSTRUCT::structValue() {
std::cout << "CTESTSTRUCT::setValue Called" << std::endl;
return CTESTSTRUCT::CTESTUNION::var1;
}
CTest::~CTest() {
std::cout << "Distructor Called" << std::endl;
}
//*********************************************************************************
#include <iostream>
#include "CTest.h"
using namespace std;
CTest * ctestObj;
int main() {
ctestObj = new CTest(25);
int returnVal = ctestObj->getValue();
std::cout << "Value Returned: " << returnVal << std::endl;
std::cout << "structVal: " << std::endl;
//CTest::CTESTSTRUCT::testVal = 10;
delete ctestObj;
return 0;
}
What you're actually trying to do is have an instance of a struct inside your class. What you did was define a class within your class (which did not actually give your class a member of that type, but only scoped its definition).
So what you need to do is pull our the struct, from the class:
struct CTESTSTRUCT
{
// ...
};
And then give CTest a member of type CTESTSTRUCT
class CTest {
int value;
public:
CTest(int);
int getValue();
CTESTSTRUCT test;
~CTest();
};
Now you can access it like so:
int main() {
CTest * ctestObj;
ctestObj = new CTest(25);
int returnVal = ctestObj->getValue();
std::cout << "Value Returned: " << returnVal << std::endl;
std::cout << "structVal: " << std::endl;
ctestObj->test.testVal = 10;
delete ctestObj;
return 0;
}

C++ - friend functions

I am trying to make a simple friend function work, but not in just one source file. I seem to get an error and I can't seem to find an answer why.
Please have a look at my code:
----------classOne.h--------------
#ifndef CLASSONE_H_
#define CLASSONE_H_
using namespace std;
class ClassOne {
private:
int m_a;
int m_b;
public:
ClassOne(int a, int b);
void printValuesOne();
friend void ClassTwo::twoPrintsOne();
};
-
----------classOne.cpp------------
#include <iostream>
#include "classOne.h"
using namespace std;
ClassOne::ClassOne(int a, int b) {
m_a = a;
m_b = b;
}
void ClassOne::printValuesOne() {
cout << "m_a: " << m_a << " " << "m_b: " << m_b << endl;
}
.
----------classTwo.h-------------
#ifndef CLASSTWO_H_
#define CLASSTWO_H_
using namespace std;
class ClassTwo {
private:
int m_c;
int m_d;
public:
ClassTwo(int c, int d);
void printValuesTwo();
twoPrintsOne();
};
#endif
-
---------classTwo.cpp-----------
#include <iostream>
#include "classTwo.h"
using namespace std;
ClassTwo::ClassTwo(int c, int d) {
m_c = c;
`enter code here`m_d = d;
}
void ClassTwo::printValuesTwo() {
cout << "m_c: " << m_c << " " << "m_d: " << m_d << endl;
}
void twoPrintsOne() {
cout << "ClassTwo: " << m_a: " << m_a << " " << "m_b: " << m_b << endl;
}
Basically ClassOne and ClassTwo are the same sort of thing, but only one of ClassTwo's method has access to all of ClassOne's members, so ClassTwo can print ClassOne's member variables. However, when I try to compile the whole program (I haven't provided the main method here), I get this error an error:
classOne.h:19:15: error: ‘ClassTwo’ has not been declared
friend void ClassTwo::twoPrintsOne();
^
Can someone help and explain?
ClassOne doesn't know about ClassTwo, therefore it cannot befriend with any of its methods. You have to add:
#include "classTwo.h"
on top of your classOne.h.
You are getting confused with what "friend" is supposed to do.
"friending" ClassTwo will allow ClassTwo to access the private members of ClassOne as if they were public.
It will not link those members between the two classes in any way.
You could have ClassTwo inherit from ClassOne, or add a ClassOne member in ClassTwo

C++ header issue involving functions and scope

My problem is in the following C++ code. On the line with the 'cout' I get the error:
"'number' was not declared in this scope".
.h
using namespace std;
class a{
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
int main(){
cout << "Your number is: " << number() << endl;
return 0;
}
number(){
int x = 1;
return x;
}
Note: I'm aware this isn't the cleanest code. I just wanted to get the function working and refresh my memory on how to use headers.
For minimal fix, three basic changes are necessary.
Proper implementation of the number() method
int a::number() {
int x = 1;
return x;
}
Proper invocation of the number() method
a aObject;
cout << "Your number is: " << aObject.number() << endl;
There are many other enhancements possible though.
Addition, as pointed out by #CPlusPlus, usable scope of number() method, for example declaring it public
class a{
public:
int number();
};
Try this in your cpp file
using namespace std;
#include <iostream>
#include "header.h"
void a::number()
{
int x = 1;
return x;
}
int main()
{
cout << "Your number is: " << a().number() << endl;
return 0;
}
As for your header file replace class with a struct. The reason you are getting this error is because the compiler cant find the variable number. It is actually a method of a class.The reason you are replacing the class with a struct is because by default everything in a struct is public. So your header file called header.h should look like this
using namespace std;
struct a
{
int number();
};
There are three issues with your code.
The definition of the function number().
As you declared, it is a member function of the class "a". In your .cpp, the class name should be used as a prefix to the function. I mean,
a::number(){
int x = 1;
return x;
}
As the function is a member of the class "a", there are only two ways of accessing it,
If the function is a static function in the class, you can access it with :: operator. Like a::number().
If the function is not a static function, that is true in your case, you should instantiate the object out of the class "a" and they use "." operator with the reference. I mean,
a obj;
obj.number().
Your function number() is declared in private scope. You may recall that by default the scope is a class is private unless you specify public or protected. So the private function number() cannot be used outside the declared class unless there is a friend to it.
Below the code that I fixed,
.h
using namespace std;
class a{
public:
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
a::number(){
int x = 1;
return x;
}
int main(){
a obj;
cout << "Your number is: " << obj.number() << endl;
return 0;
}

Static Data Members

Please have a look at the following code
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(int);
~GameObject(void);
int id;
private:
GameObject(void);
};
GameObject.cpp
#include "GameObject.h"
#include <iostream>
using namespace std;
static int counter = 0;
GameObject::GameObject(void)
{
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
//GameObject obj1;
//cout << obj1.id << endl;
GameObject obj2(45);
cout << obj2.id << endl;;
// cout << obj2.counter << endl;
GameObject obj3(45);
GameObject obj4(45);
GameObject obj5(45);
//Cannot get Static value here
//cout << "Number of Objects: " << GameObject
//
system("pause");
return 0;
}
Here, I am trying to record how many instances have been created. I know it can be done by a static data member, but I can't access it withing the Main method! Please help!
PS:
I am seeeking for a direct access, without a getter method
Your static variable, counter cannot be accessed because it isn't a member of GameObject. If you want to access the counter, you'll need to do something like this:
GameObject.h
#pragma once
class GameObject
{
public:
...
static int GetCounter();
...
};
GameObject.cpp
int GameObject::GetCounter()
{
return counter;
}
Then you can access the variable like:
cout << "Number of Objects: " << GameObject::GetCounter();
Of course, there are other ways of accessing a static variable, such as making the counter variable a static member of your GameObject class (which I would recommend).
In your code, counter is not a static member of your class, but just a good old global variable. You can read up on how to declare static member variables anywhere on the net, but here are some snippets:
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(void);
GameObject(int);
~GameObject(void);
private:
int id;
// static members
public:
static int counter; // <<<<<<<<<<< declaration
};
ameObject.cpp
#include "GameObject.h"
int GameObject::counter = 0; // <<<<<<<<<<< instantiation
GameObject::GameObject(void)
{
counter++;
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
GameObject obj2(45);
cout << "version one: " << obj2.counter << endl;
// second version:
cout << "version two: " << GameObject::counter << endl;
system("pause");
return 0;
}
Afaik accessing static members on an instance of that class should work fine, but it gives the wrong impression, you should prefer version two.
Never mind, I did it with a getter method. Closing thread