Reading
-------------------------------------------------------------------------------------------------------------------
static variables in functions
--------------------------------------------------------------------------------------------------------------------
you can create a static variable inside a function
its value will stay in memory even after it is called and will be still have its previous value when called again
for example
File: main1.cpp
#include "cmpslib19.h"
void SampleFunction(int val)
{
int x=0; // x only exists during the scope of this single function call. The memory used is cleaned up every time
cout << "x=" << x << ", val=" << val ;
x += val;
cout << ", now x=" << x << endl;
}
void SampleFunction2(int val)
{
static int x=0;// x will be created , set to 0 and remain in memory for future calls to the function
cout << "x=" << x << ", val=" << val ;
x += val;
cout << ", now x=" << x << endl;
}
int main()
{
for (auto loop=0;loop < 10;loop++)
SampleFunction(loop);
cout << "\n\nnow where x is a static variable\n\n";
for (auto loop=0;loop < 10;loop++)
SampleFunction2(loop);
return 0;
}
when run it produces the output
File: output.txt
x=0, val=0, now x=0
x=0, val=1, now x=1
x=0, val=2, now x=2
x=0, val=3, now x=3
x=0, val=4, now x=4
x=0, val=5, now x=5
x=0, val=6, now x=6
x=0, val=7, now x=7
x=0, val=8, now x=8
x=0, val=9, now x=9
now where x is a static variable
x=0, val=0, now x=0
x=0, val=1, now x=1
x=1, val=2, now x=3
x=3, val=3, now x=6
x=6, val=4, now x=10
x=10, val=5, now x=15
x=15, val=6, now x=21
x=21, val=7, now x=28
x=28, val=8, now x=36
x=36, val=9, now x=45
In the second function where x is declared to be static it will retain its value from the previous call to the function.
-------------------------------------------------------------------------------------------------------------------
static class data members
--------------------------------------------------------------------------------------------------------------------
we can create static class members
ALL instances of a class that are created share that single static data member
for example
File: main1.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
double lab_scores[28];
double hw_scores[14];
static string instructor;
};
int main()
{
cmps2020_student s1; // s1 is an "instance" of the cmps2020_student class
cmps2020_student s2; // s2 is another instance
cmps2020_student s3;
cmps2020_student s4;
// now we have 4 "instances" of the cmps2020_student class
s1.instructor = "Sarr";
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
return 0;
}
s1,s2,s3 and s4 all share on single string named instructor
but we run into a problem when we try to compile it
File: output1.txt
/usr/bin/ld: /tmp/cctT6s3u.o: warning: relocation against `_ZN16cmps2020_student10instructorB5cxx11E' in read-only section `.text'
/usr/bin/ld: /tmp/cctT6s3u.o: in function `main':
main1.cpp:(.text+0x52): undefined reference to `cmps2020_student::instructor[abi:cxx11]'
/usr/bin/ld: main1.cpp:(.text+0x5e): undefined reference to `cmps2020_student::instructor[abi:cxx11]'
/usr/bin/ld: main1.cpp:(.text+0x86): undefined reference to `cmps2020_student::instructor[abi:cxx11]'
/usr/bin/ld: main1.cpp:(.text+0xae): undefined reference to `cmps2020_student::instructor[abi:cxx11]'
/usr/bin/ld: main1.cpp:(.text+0xd6): undefined reference to `cmps2020_student::instructor[abi:cxx11]'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
this is because we have to explicity create the static members outside the class.
static variables behave differently than regular members so we have to declare them differently
like so
File: main2.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
double lab_scores[28];
double hw_scores[14];
static string instructor;
};
// we must actually create the static classe members outside the class
// this declares a string
string cmps2020_student::instructor;
int main()
{
cmps2020_student s1;
cmps2020_student s2;
cmps2020_student s3;
cmps2020_student s4;
s1.instructor = "Sarr";
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
return 0;
}
now it will compile and we can run it
File: output2.txt
ASSIGNING DEFAULT VALUES
we can assign them values in the constructor unless we want them to be reset everytime a new
instance of the class is created
File: main3.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
double lab_scores[28];
double hw_scores[14];
static string instructor;
};
// we must actually create the static classe members outside the class
// this declares a string
// this is where you can assign it a default value as well
// NOTE: if you are going to have static class members you should
// have your class split into a .h and .cpp
// put this in the .cpp file along with your function bodies
// if you dont you will have linking errors when trying to compile
string cmps2020_student::instructor = "Sarr";
int main()
{
cmps2020_student s1;
cmps2020_student s2;
cmps2020_student s3;
cmps2020_student s4;
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
s4.instructor = "Michael"; // if we change it for one , we change for all
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
return 0;
}
output
File: output3.txt
Sarr
Sarr
Sarr
Sarr
Michael
Michael
Michael
Michael
-------------------------------------------------------------------------------------------------------------------
accessing static data members directly
--------------------------------------------------------------------------------------------------------------------
File: main4.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
double lab_scores[28];
double hw_scores[14];
static string instructor;
};
// we must actually create the static classe members outside the class
// this declares a string
// this is where you can assign it a default value as well
// NOTE: if you are going to have static class members you should
// have your class split into a .h and .cpp
// put this in the .cpp file along with your function bodies
// if you dont you will have linking errors when trying to compile
string cmps2020_student::instructor = "Sarr";
int main()
{
//static members can also be accesed directly using the scope resolution operator
//this is so we can access it without even creating any instances of our class
cmps2020_student::instructor = "Professor Peabody";
cout << cmps2020_student::instructor << endl;
cmps2020_student s1;
cmps2020_student s2;
cmps2020_student s3;
cmps2020_student s4;
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
return 0;
}
output
File: output4.txt
Professor Peabody
Professor Peabody
Professor Peabody
Professor Peabody
Professor Peabody
-------------------------------------------------------------------------------------------------------------------
static class functions
--------------------------------------------------------------------------------------------------------------------
File: main5.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
double lab_scores[28];
double hw_scores[14];
static void SetInstructor(string in){instructor=in;}
static string GetInstructor() { return instructor;}
static string instructor;
};
// we must actually create the static classe members outside the class
// this declares a string
// this is where you can assign it a default value as well
// NOTE: if you are going to have static class members you should
// have your class split into a .h and .cpp
// put this in the .cpp file along with your function bodies
// if you dont you will have linking errors when trying to compile
string cmps2020_student::instructor = "Sarr";
int main()
{
//static class functions can also be accesed directly using the scope resolution operator
//this is so we can access it without even creating any instances of our class
cmps2020_student::SetInstructor( "Professor Peabody" );
cout << cmps2020_student::GetInstructor() << endl;
cmps2020_student s1;
cmps2020_student s2;
cmps2020_student s3;
cmps2020_student s4;
cout << s1.instructor << endl;
cout << s2.instructor << endl;
cout << s3.instructor << endl;
cout << s4.instructor << endl;
return 0;
}
output
File: output5.txt
Professor Peabody
Professor Peabody
Professor Peabody
Professor Peabody
Professor Peabody
-------------------------------------------------------------------------------------------------------------------
friend functions
-------------------------------------------------------------------------------------------------------------------
File: cmps2020_student.h
#include "cmpslib19.h"
class cmps2020_student
{
private:
string name;
int id;
public:
void SetName(string in);
void SetID(int in);
friend bool AreEqual(const cmps2020_student & ,const cmps2020_student & );
}; // end cmps2020_student class declaration
File: cmps2020_student.cpp
#include "cmps2020_student.h"
// here are the bodies for our two functions that are defined as members of the class, note the name is prefixed with the classname
void cmps2020_student::SetName(string in){name=in;}
void cmps2020_student::SetID(int in){id=in;}
// the friend function is NOT part of the class , note we are not prefixing the function name with the class name
// no cmps2020_student:: this function is NOT part of the class
bool AreEqual(const cmps2020_student & v1,const cmps2020_student & v2)
{
// in this context name and id are private data members
// if this was not declared to be a friend inside the class
// the following line would not compile
if (v1.name == v2.name && v1.id == v2.id)
return true;
return false;
}
File: main1.cpp
#include "cmpslib19.h"
#include "cmps2020_student.h"
int main()
{
cmps2020_student s1;
s1.SetID(234234234);
s1.SetName("Brad Majors");
cmps2020_student s2;
s2.SetID(456456456);
s2.SetName("Magenta");
// here we can test out the AreEqual funtion
// it will compare the name and id of both studants passed to it
// even though they are private and the AreEqual function is not
// a member of the class it still works because we declared it to be a friend
cout << "does s1 == s2 " << boolalpha << AreEqual(s1,s2) << endl;
return 0;
}
friend functions are particularly useful for operator overloading and for converting old c code with structures to c++ classes