How to initialize static variable in a loop?

I am attempting to automate the testing of Employee class (see code below).
Each iteration of the loop is a new test case.
Each iteration of the loop instantiates and destroys employee objects to insure that each test case starts in an initial state.

The following code runs, but the static manager persists across test cases.
Is there a way to instantiate and destroy static manager object in the loop?
I need to insure that manager object starts in initial state for each test case.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		void print() { std::cout << " " << j++; }
};


class Employee
{
    private:
	static Manager& refManager;	//declare class static variable in class
    public:
	void fn() { refManager.print(); }
};

Manager manager;
Manager& Employee::refManager = manager; //initialize static variable outside of class

int main()
{
	for (int i=0; i<2; i++)		//test loop, one testcase per iteration
	{
		Employee e1;		//Employee objects being tested
		Employee e2;
					//expected output
		e1.fn();		// 0
		e2.fn();		// 1
		/*Employee destructor is automatically called
		  because its scope of existence has finished */
	}
}

output:
 0 1 2 3

Thank you.
Last edited on
Add method to Manager which will reset internal state.
Another way is to manually destroy object (by calling a destructor) and recreate it (by using placement new)
Thanks MiiNiPaa.

I found a third way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};


class Employee
{
	private:
	public:
		static Manager& refManager;	//declare class static variable in class
		void fn() { refManager.print(); }
};

Manager manager;
Manager& Employee::refManager = manager; //initialize static variable outside of class

int main()
{
	for (int i=0; i<2; i++)		//test loop, one testcase per iteration
	{
		Manager manager1;
		Employee::refManager = manager1; //reset

		Employee e1;		//Employee objects being tested
		Employee e2;
					//expected output
		e1.fn();		// 0
		e2.fn();		// 1
		/*Employee destructor is automatically called
		  because its scope of existence has finished */
	}
}

output:
 0 1 0 1
It is actually a subclass of 2.
Even more effective approach:
1
2
3
4
5
6
7
8
9
int main()
{
	Manager blank_manager;
	for (int i=0; i<2; i++)
	{
		Employee::refManager = blank_manager;
		/*...*/
	}
}
I am surprised that works, but it does.
It's as if line 29 (below) is copy by value.
But the syntax on line 17 says copy by reference.
What is happening?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};


class Employee
{
	private:
	public:
		static Manager& refManager;	//declare class static variable in class
		void fn() { refManager.print(); }
};

Manager manager;
Manager& Employee::refManager = manager; //initialize static variable outside of class

int main()
{
	Manager manager1;
	for (int i=0; i<2; i++)		//test loop, one testcase per iteration
	{
		Employee::refManager = manager1; //reset

		Employee e1;		//Employee objects being tested
		Employee e2;
					//expected output
		e1.fn();		// 0
		e2.fn();		// 1
		/*Employee destructor is automatically called
		  because its scope of existence has finished */
	}
}

output:
 0 1 0 1
Last edited on
Why does the above code reset manager1 with each iteration of loop, and the following code does not reset manager?

Line 28 is different:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};


class Employee
{
	private:
	public:
		static Manager& refManager;	//declare class static variable in class
		void fn() { refManager.print(); }
};

Manager manager;
Manager& Employee::refManager = manager; //initialize static variable outside of class

int main()
{
	for (int i=0; i<2; i++)		//test loop, one testcase per iteration
	{
		Employee::refManager = manager; //not resetting

		Employee e1;		//Employee objects being tested
		Employee e2;
					//expected output
		e1.fn();		// 0
		e2.fn();		// 1
		/*Employee destructor is automatically called
		  because its scope of existence has finished */
	}
}

output:
 0 1 2 3
Because refManager is already pointing to manager.
I get the feeling that there is some fundamental C++ rule needed to make sense of the above two examples.
The only difference is that 'manager' is global scope while 'manager1' is local scope.

This is copy by reference (line 28 posted 9:56pm):
Employee::refManager = manager; //manager is global

Is this copy by value? (line 29 posted 8:42pm):
Employee::refManager = manager1;//manager1 is instantiated locally

The syntax is the same. What C++ rule causes manager1 to copy by value?
Your initialisation:
1
2
3
4
5
6
Manager manager;
Manager& Employee::refManager = manager; 
//This makes Employee::refManager  an alias for manager
//When you are changing refManager, you are actually changing manager
//You can substitute Employee::refManager with manager 
//and (assumung both are visible) it will behave the same 


So Employee::refManager = manager; can be rewritten as manager = manager; Do you see the problem now?
Now I see what you mean. Thank you for explaining.
Here is a simplified version:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};

Manager manager0;
Manager& refManager = manager0;		//refManager is an alias of manager0

int main()
{
	Manager manager1;

	for (int i=0; i<2; i++)	
	{
		refManager = manager1;	//copy by value
		refManager.print();
	}
}

output:
 0 0


It's more explicit when written in pointer notation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};

Manager manager0;
Manager* const ptrManager = &manager0;	//pointer

int main()
{
	Manager manager1;

	for (int i=0; i<2; i++)
	{
		*ptrManager = manager1;	//copy by value
		ptrManager->print();
	}
}

output:
 0 0


Even simpler without reference or pointers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

class Manager
{
	private:
		int j;
	public:
		Manager(): j(0) { }
		void print() { std::cout << " " << j++; }
};

Manager manager0;


int main()
{
	Manager manager1;

	for (int i=0; i<2; i++)	
	{
		manager0 = manager1;	//copy by value
		manager0.print();
	}
}

output:
 0 0
Last edited on
Topic archived. No new replies allowed.