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

Sarr
Sarr
Sarr
Sarr

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