Pointers to member functions of classes

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <iostream>
#include <string>
using namespace std;



class Aircraft
{
public:
        Aircraft() : MPrice(0), LPrice(0), BPrice(0), PPrice(0), TotalPrice(0) , Stars(0) {cout<<"aircraft constructor"<<endl;}
        virtual ~Aircraft(){cout<<"aircraft destructor"<<endl;}

protected:
	string Missile;
	string Laser;
	string Bomb;
	string Propulsion;
	int MPrice, LPrice, BPrice, PPrice, TotalPrice;
	int Stars;
};

class Jet : public Aircraft
{
public:
	 string GetMissile() {return Missile;}
	 int MissilePrice() {return MPrice;}

	 string GetLaser() {return Laser;}
	 int LaserPrice() {return LPrice;}

	 string GetBomb() {return Bomb;}
	 int BombPrice() {return BPrice;}

	 string GetPropulsion() {return Propulsion;}
	 int PropulsionPrice() {return PPrice;}

	 void SetMissile(int MissileChoice)
	 {
		 switch(MissileChoice)
		 {
			 
		 case 0:  Missile = "Air-to-air missile"; 
					MPrice = 300;
					break;
		 case 1:  Missile = "Air-to-surface missile"; 
					MPrice = 700;
					break;
		 case 2:  Missile = "Air-to-ship missile"; 
					MPrice = 600;
					break;
		 case 3:  Missile = "Air-to-tank missile"; 
					MPrice = 400;
					break;
		 }
	 }
	 void SetLaser(int LaserChoice)
	 {
		 switch(LaserChoice)
		 {
		 case 0:  Laser = "Hydrogen Fluoride Laser"; 
					LPrice = 100;
					break;
		 case 1:  Laser = "Deuterium Fluoride Laser"; 
					LPrice = 250;
					break;
		 case 2:  Laser = "Chemical Oxygen-Iodine Laser"; 
					LPrice = 200;
					break;
		 case 3:  Laser = "All Gas-phase Iodine Laser"; 
					LPrice = 125;
					break;
		 }
	 }
	void SetBomb(int BombChoice)
	 {
		 switch(BombChoice)
		 {
		 case 0:	Bomb = "Cluster Bomb"; 
					BPrice = 600;
					break;
		 case 1:  Bomb = "Concrete Bomb"; 
					BPrice = 700;
					break;
		 case 2:  Bomb = "Incendiary Bomb"; 
					BPrice = 850;
					break;
		 case 3:  Bomb = "General-purpose Bomb"; 
					BPrice = 600;
					break;
		 }
	 }
	void SetPropulsion(int PropulsionChoice)
	 {
		 //Jet.Propulsion
		 switch(PropulsionChoice)
		 {
		 case 0:  Propulsion = "Solid-fuel Propulsion"; 
					PPrice = 750;
					break;
		 case 1:  Propulsion = "Liquid Rocket Propulsion"; 
					PPrice = 900;
					break;
		 case 2:  Propulsion = "Electric Propulsion"; 
					PPrice = 450;
					break;
		 case 3:  Propulsion = "Nuclear Propulsion"; 
					PPrice = 650;
					break;
		 }
	 }

	int GetTotalPrice() {TotalPrice = MPrice+LPrice+BPrice+PPrice;
							return TotalPrice;}
	int GetStars(int (*pGTPrice)() )//accepts as argument a pointer (pStars) to 'int GetTotalPrice()'
	{if (pGTPrice()>=2400)
		{Stars = 12;
		return Stars;}
	if (pGTPrice()>=2300 && pGTPrice()<2400)
		{Stars = 11;
		return Stars;}
	if (pGTPrice()>=2200 && pGTPrice()<2300)
		{Stars = 10;
		return Stars;}
	if (pGTPrice()>=2100 && pGTPrice()<2200)
		{Stars = 9;
		return Stars;}
	if (pGTPrice()>=2000 && pGTPrice()<2100)
		{Stars = 8;
		return Stars;}
	if (pGTPrice()>=1900 && pGTPrice()<2000)
		{Stars = 7;
		return Stars;}
	if (pGTPrice()>=1800 && pGTPrice()<1900)
		{Stars = 6;
		return Stars;}
	if (pGTPrice()>=1700 && pGTPrice()<1800)
		{Stars = 5;
		return Stars;}
	if (pGTPrice()>=1600 && pGTPrice()<1700)
		{Stars = 4;
		return Stars;}
	if (pGTPrice()>=1500 && pGTPrice()<1600)
		{Stars = 3;
		return Stars;}
	if (pGTPrice()>=1400 && pGTPrice()<1500)
		{Stars = 2;
		return Stars;}
	if (pGTPrice()<1400)
		{Stars = 1;
		return Stars;}

	};
};


int main()
{
	Jet You;
	int MissileChoice, LaserChoice, BombChoice, PropulsionChoice;
	cout<<"choose the missile, laser, bomb, propulsion of the jet"<<endl;
	cin>>MissileChoice;
	cin>>LaserChoice;
	cin>>BombChoice;
	cin>>PropulsionChoice;
	You.SetMissile(MissileChoice);
	You.SetLaser(LaserChoice);
	You.SetBomb(BombChoice);
	You.SetPropulsion(PropulsionChoice);
	cout<<"you chose "<<endl;
	cout<<You.GetMissile()<<endl;
	cout<<You.GetLaser()<<endl;
	cout<<You.GetBomb()<<endl;
	cout<<You.GetPropulsion()<<endl;
	cout<<"Thus, total price is "<<You.GetTotalPrice();
	
        int (Aircraft::*pPrice) () = 0;
	Aircraft* ptr=0;
	ptr=new Jet;
	pPrice=Aircraft::GetTotalPrice;
        cout<<"You have produced a "<<ptr->*GetStars(pPrice())<<"-starred JET!";
	delete ptr;

	cin.ignore();
	cin.ignore();


return 0;
}


The code worked well until I added the GetStars() function and the last few lines, starting from int (Aircraft::*pPrice) () = 0; to delete ptr;. Does anyone know whats wrong with this?
Class Aircraft has no such function GetTotalPrice

So this expression Aircraft::GetTotalPrice is invalid.

This class has no any function.
Last edited on
ok I changed it to pPrice=Jet::GetTotalPrice, but I'm still getting error messages for that line and the one below it
You are assigning the *pPrice memory location the address of the function Aircraft::GetTotalPrice. instead, use

Jet->GetTotalPrice();

Or

*Jet.GetTotalPrice();
Last edited on
changing it to pPrice=Jet->GetTotalPrice(); or pPrice=*Jet.GetTotalPrice() didn't help. Trying pPrice=ptr->GetTotalPrice() also didn't help

Oh i see what you want to do. You want to pass Jet.GetTotalPrice() as a argument to Jet.GetStars(int (*ptr)()).

You know this seems slow to me. You have an hierarchy of If control structures which call the Jet.GetTotalPrice() function every step of the way.

Just have GetStars() call GetTotalPrice() from within the function.

so instead of this:
1
2
3
4
5
int (Aircraft::*pPrice) () = 0;
	Aircraft* ptr=0;
	ptr=new Jet;
	pPrice=Aircraft::GetTotalPrice;
        cout<<"You have produced a "<<ptr->*GetStars(pPrice())<<"-starred JET!";


you would have this:
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
40
41
42
43
44
45
46
47
48
//class jet
int GetStars()
	{
int Price = GetTotalPrice()
if (Price>=2400)
		{Stars = 12;
		return Stars;}
	if (Price>=2300 && Price<2400)
		{Stars = 11;
		return Stars;}
	if (Price>=2200 &&Price<2300)
		{Stars = 10;
		return Stars;}
	if (Price>=2100 && Price<2200)
		{Stars = 9;
		return Stars;}
	if (Price>=2000 && Price<2100)
		{Stars = 8;
		return Stars;}
	if (Price>=1900 && Price<2000)
		{Stars = 7;
		return Stars;}
	if (Price>=1800 &&Price<1900)
		{Stars = 6;
		return Stars;}
	if (Price>=1700 && Price<1800)
		{Stars = 5;
		return Stars;}
	if (Price>=1600 && Price<1700)
		{Stars = 4;
		return Stars;}
	if (Price>=1500 && Price<1600)
		{Stars = 3;
		return Stars;}
	if (Price>=1400 && Price<1500)
		{Stars = 2;
		return Stars;}
	if (Price<1400)
		{Stars = 1;
		return Stars;}

	};

//-----------------------------------
//main
	Aircraft* ptr=0;
	ptr=new Jet;
        cout<<"You have produced a "<<ptr->GetStars()<<"-starred JET!";



This way the function only gets called once per iteration. its also easier to read.

This works because both GetStars() and GetTotalPrice() are methods of the same class, so they can "see" each other.

Besides if you were going to do this it would have been:
 
int (Jet::*ptr)()  = Jet::GetTotalPrice;


and not (Aircraft::*Price)()

GetTotalPrice() is a method of Jet, and not Aircraft. (it should be, if you ask me. All aircraft have a total price.)

Last edited on
ok, I made the changes, but I'm now getting errors saying
"error C2039: 'GetStars' : is not a member of 'Aircraft'"
and " see declaration of 'Aircraft'"
Then change

Aircraft* ptr = 0;
to
Jet* ptr = new Jet;
ok, it works now, except I always get 0 as an output for 0-starred jet. So when GetStars() takes in GetTotalPrice(), GetTotalPrice() is always 0 instead of 1800 or whatever. So doesn't GetStars() need to take GetTotalPrice as an argument, like I had it before?

1
2
3
4
5
int (Jet::*pPrice) ()= 0;
	Jet* ptr=0;
	ptr=new Jet;
	pPrice=Jet::GetTotalPrice;
	cout<<"You have produced a "<<ptr->GetStars(pPrice)<<"-starred JET!";


when I tried this in the previous method, I'm still getting an error saying that
int(Jet::*)() is incompatible with parameter of type int(*)() on the line cout<<"You have produced a "<<ptr->GetStars(pPrice)<<"-starred JET!";

I then tried changing GetStars to int GetStars(int (Jet::*pGTPrice)() ), but that didn't help things either
Last edited on
While we are at it - I may be a bit late - but all of this:

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
if (Price>=2400)
		{Stars = 12;
		return Stars;}
	if (Price>=2300 && Price<2400)
		{Stars = 11;
		return Stars;}
	if (Price>=2200 &&Price<2300)
		{Stars = 10;
		return Stars;}
	if (Price>=2100 && Price<2200)
		{Stars = 9;
		return Stars;}
	if (Price>=2000 && Price<2100)
		{Stars = 8;
		return Stars;}
	if (Price>=1900 && Price<2000)
		{Stars = 7;
		return Stars;}
	if (Price>=1800 &&Price<1900)
		{Stars = 6;
		return Stars;}
	if (Price>=1700 && Price<1800)
		{Stars = 5;
		return Stars;}
	if (Price>=1600 && Price<1700)
		{Stars = 4;
		return Stars;}
	if (Price>=1500 && Price<1600)
		{Stars = 3;
		return Stars;}
	if (Price>=1400 && Price<1500)
		{Stars = 2;
		return Stars;}
	if (Price<1400)
		{Stars = 1;


Can be reduced to one line of code:
Stars = Price < 1400 ? 1 : Price > 2400? 12: (Price - 1400)/100 +2;
Last edited on
That's because you are not getting the purchase price of the Jet You, but the purchase price of Jet* ptr, which has no values assigned.
ok, I finally got it to work! thanks for the help

btw, with my old method of having GetStars accepting GetTotalPrice as an argument, why is the code below incorrect?
1
2
3
4
5
int (Jet::*pPrice) ()= 0;
	Jet* ptr=0;
	ptr=new Jet;
	pPrice=Jet::GetTotalPrice;
	cout<<"You have produced a "<<ptr->GetStars(pPrice)<<"-starred JET!";
That wasn't the original implementation. It was Aircraft::GetTotalPrice.

Look at the original member method of Jet::GetStars(int (*ptr)()). Notice that it takes a pointer to a function that has no arguments and returns an integer. This differs from what you were trying to pass, which is a pointer to a Jet method that takes no parameters and returns an integer. In c++ there is a hidden pointer that points to the class declaration which then points to the code.

If you wanted to try and make it work you would need to change to declaration of Jet::GetStars(int (*ptr)()) to Jet::GetStars(int(Jet::*ptr)()).
Topic archived. No new replies allowed.