Can't get this program to compile!

I've been at this same program for weeks now and I can't figure out what the heck is wrong. Its a 3 file program, 2 cpp files, and 1 header file. Here is the coding...

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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
//Resistor Main
#include "Resistor.h"

#include <iostream>
#include <iomanip>
#include <Windows.h>
#include <math.h>

using namespace std;

//EIA Standard array element sizes per tolerance class
const int E12 = 12;
const int E24 = 24;
const int E48 = 48;
const int E96 = 96;

//EIA Standard Resistor Values
//E12   10% tolerance
//E24     5% tolerance
//E48     2% tolerance
//E96     1% tolerance

//10% standard values
const int nominalE12Values[E12] = 
	{	100, 120, 150, 180, 220, 270,
		330, 390, 470, 560, 680, 820};

//5% standard values
const int nominalE24Values[E24] = 
	{	100, 110, 120, 130, 150, 160, 180, 200, 220, 240,
		270, 300, 330, 360, 390, 430, 470, 510, 560, 620,
		680, 750, 820, 910};

//2% standard values
const int nominalE48Values[E48] = 
	{	100, 105, 110, 115, 121, 127, 133, 140, 147, 154, 
		162, 169, 178, 187, 196, 205, 215, 226, 237, 249,
		261, 274, 287, 301, 316, 332, 348, 365, 383, 402,
		422, 442, 464, 487, 511, 536, 562, 590, 619, 649,
		681, 715, 750, 787, 825, 866, 909, 953};

//1% standard values
const int nominalE96Values[E96] = 
	{	100, 102, 105, 107, 110, 113, 115, 118, 121, 124,
		127, 130, 133, 137, 140, 143, 147, 150, 154, 158,
		162, 165, 169, 174, 178, 182, 187, 191, 196, 200,
		205, 210, 215, 221, 226, 232, 237, 243, 249, 255,
		261, 267, 274, 280, 287, 294, 301, 309, 316, 324,
		332, 340, 348, 357, 365, 374, 383, 392, 402, 412,
		422, 432, 442, 453, 464, 475, 487, 499, 511, 523,
		536, 549, 562, 576, 590, 604, 619, 634, 649, 665,
		681, 698, 715, 732, 750, 768, 787, 806, 825, 845,
		866, 887, 909, 931, 953, 976};


void DisplayResistance(Resistor &, bool );
void EnterResistance(Resistor &, bool);


void main(void)
{


	//Control variable to display function names when called
	bool fnDisp = false;

	Resistor Res1(4700.0, 0.10, "Res1", fnDisp);
	Resistor Res2(330.0, 0.10, "Res2", fnDisp);
	Resistor Res3(10000.0,0.10, "Res3", fnDisp);

	DisplayResistance(Res1, fnDisp);
	DisplayResistance(Res2, fnDisp);
	DisplayResistance(Res3, fnDisp);
		
	EnterResistance(Res1, fnDisp);
	DisplayResistance(Res1, fnDisp);

	system("pause");
}


// Function displays all data member values of a Resistor object
void DisplayResistance(Resistor & resObj, bool fnDisplay)
{
	//Local variables to hold Resistor data copies
	double nom, tol, min, max;
	nom = resObj.getNom(fnDisplay);
	tol = resObj.getTol(fnDisplay);
	min = nom * (1.0 - tol);
	max = nom * (1.0 + tol);
	cout << endl << "Resistor object name is " << resObj.getName(fnDisplay) << endl;
	cout << setiosflags(ios::fixed) << setiosflags(ios::showpoint)
		<< setprecision(3);
	cout << endl << "Nominal resistance value = " << setw(15) << nom << " ohms ";
	cout << endl << "Tolerance =                " << setw(15) << tol * 100 << " %";
	cout << endl << "Minimum Resistance =       " << setw(15) << min << " ohms";
	cout << endl << "Maximum Resistance =       " << setw(15) << max << " ohms";
	cout << endl << endl;
}

// Function allows user to enter new values for Resistor data members
void EnterResistance(Resistor & resObj, bool fnDisplay)
{
	//Local variables to hold Resistor data copies
	double nom, tol;
	string name;
	
	//Local variable for user data entry
	int nomEdit = 0;
	int tolEdit = 0;
	int powerOfTen = 0;

	//Valid EIA entry value check boolean
	bool validEIA = false;

	//Local loop counter
	int i = 0;

	nom = resObj.getNom(fnDisplay);
	tol = resObj.getTol(fnDisplay);
	name = resObj.getName(fnDisplay);
	cout << endl << endl;
	cout << "Resistor being edited:  " << name << endl << endl;

	do
	{
		cout << "Current resistance tolerance = " << tol * 100 << " %" << endl;
		cout << "Valid tolerances are 1%, 2%, 5% or 10%" << endl << endl;
		cout << "Enter 1, 2, 5 or 10:  ";
		cin >> tolEdit;
		cout << endl;
	}
	while(tolEdit != 1 && tolEdit != 2 && tolEdit != 5 && tolEdit != 10);

	cout << "Tolerance set to " << tolEdit << " %" << endl << endl;
	resObj.setTol((double)tolEdit*0.01, fnDisplay);

	do
	{
		cout << "Current nomimal resistance = " << nom << " ohms" << endl;
		cout << "Standard 10% Resistance Values, First Three Digits" << endl << endl;

		if(tolEdit == 10)
		{
			for( i = 0; i < E12; i++)
			{
				if(!(i % 10))
					cout << endl;
				cout << nominalE12Values[i] << "   ";
			}
		}
		else if(tolEdit == 5)
		{
			for( i = 0; i < E24; i++)
			{
				if(!(i % 10))
					cout << endl;
				cout << nominalE24Values[i] << "   ";
			}
		}
		else if(tolEdit == 2)
		{
			for( i = 0; i < E48; i++)
			{
				if(!(i % 10))
					cout << endl;
				cout << nominalE48Values[i] << "   ";
			}
		}
		else
		{
			for( i = 0; i < E96; i++)
			{
				if(!(i % 10))
					cout << endl;
				cout << nominalE96Values[i] << "   ";
			}
		}

		cout << endl << endl << "Enter first three digits:  ";
		cin >> nomEdit;
		cout << "You entered " << nomEdit << endl;
		validEIA = false;


		if(tolEdit == 10)
		{
			for( i = 0; i < E12; i++)
			{
				if(nomEdit == nominalE12Values[i])
				{
					validEIA = true;
					cout << "Valid EIA value entered" << endl;
				}
			}
		}
		else if(tolEdit == 5)
		{
			for( i = 0; i < E24; i++)
			{
				if(nomEdit == nominalE24Values[i])
				{
					validEIA = true;
					cout << "Valid EIA value entered" << endl;
				}
			}
		}
		else if(tolEdit == 2)
		{
			for( i = 0; i < E48; i++)
				{
				if(nomEdit == nominalE48Values[i])
				{
					validEIA = true;
					cout << "Valid EIA value entered" << endl;
				}
			}
		}
		else
		{
			for( i = 0; i < E96; i++)
				{
				if(nomEdit == nominalE96Values[i])
				{
					validEIA = true;
					cout << "Valid EIA value entered" << endl;
				}
			}
		}

		if (validEIA == false)
			{
				cout << "Invalid EIA value entered, try again" << endl;
			}
	}
	while(validEIA == false);


	do
	{
		cout << endl << "Enter a power of ten multiplier between -2 (0.01) and 3 (1000):  ";
		cin >> powerOfTen;
		cout << "You entered " << powerOfTen << endl;
	}
	while(powerOfTen < -2 || powerOfTen > 3);

	resObj.setNom((double)nomEdit * pow(10.0,(double)powerOfTen), fnDisplay);
}


...This is the next cpp file.

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
//Resistor.cpp
#include "Resistor.h"

#include <iostream>
#include <string>
using namespace std;

//constructor
Resistor::Resistor(double n, double t, string nm, bool display)
{
	nom = nom;
	tol = tol;
	name = name;
	if(display){
		cout<<"constructor was called"<<endl;
	}
}
//functions
void Resistor::setNom(double n, bool display){
	nom=n;
	if(display){
		cout<<"Set Nom was called"<<endl;
	}
}
void Resistor::setTol(double t, bool display){
	tol=t;
	if(display){
		cout<<"Set Tol was called"<<endl;
	}
}
void Resistor::setName(string nm, bool display){
	name=nm;
	if(display){
		cout<<"Set Name was called"<<endl;
	}
}
double Resistor::getNom(bool display)
{
	
	if(display){
		cout<<"Set Nom was called"<<endl;
		return nom;
	}
}
double Resistor::getTol(bool display)
{

	if(display){
		cout<<"Set Tol was called"<<endl;
		return tol;
	}
}
string Resistor::getName(bool display)
{

	if(display){
		cout<<"Set Name was called"<<endl;
		return name;
	}
}


And finally my header file...

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
//Resistor.h
#ifndef resistor_H
#define resistor_H
#include <string>
using namespace std;

class Resistor
{ 
private:
double nom; 
double tol;
string name;

 
public: 
Resistor(double n, double t, string nm, bool display); 
~Resistor(); 
void setNom(double n, bool display); 
double getNom(bool display); 
void setTol(double t, bool display); 
double getTol(bool display);
void setName(string nm, bool display);
string getName (bool display);

};
#endif  



Any help is much appreciated at this time.
Here is the compiling errors that I'm getting...

1>------ Build started: Project: resist1, Configuration: Debug Win32 ------
1>Build started 1/26/2013 10:44:28 PM.
1>InitializeBuildStatus:
1> Touching "Debug\resist1.unsuccessfulbuild".
1>ClCompile:
1> Resistor.cpp
1>\\ilabss\home$\d01629872\my documents\visual studio 2010\projects\resist1\resist1\resistor.cpp(44): warning C4715: 'Resistor::getNom' : not all control paths return a value
1>\\ilabss\home$\d01629872\my documents\visual studio 2010\projects\resist1\resist1\resistor.cpp(52): warning C4715: 'Resistor::getTol' : not all control paths return a value
1>\\ilabss\home$\d01629872\my documents\visual studio 2010\projects\resist1\resist1\resistor.cpp(60): warning C4715: 'Resistor::getName' : not all control paths return a value
1>ResistorMain.obj : error LNK2019: unresolved external symbol "public: __thiscall Resistor::~Resistor(void)" (??1Resistor@@QAE@XZ) referenced in function _main
1>\\ilabss\home$\d01629872\my documents\visual studio 2010\Projects\resist1\Debug\resist1.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:03.12
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
In the header you define a destructor but there is no implementation for it anywhere.

For the warnings, you have a couple functions that claim to return values but there are some ways the function could not.
Thank you for replying.

OK for the destructor are you referring to
~resistor ();
? If so, do I really need it in my class?

Yeah I saw that which is why I have them returning nom, tol, and name. You see before I had them returning other variables. However I am still getting the errors you see before you. I'm so lost and so frustrated.
Without regard to any other errors,

1. If you do not include a destructor in the class definition the compiler will generate one for you. Since you are not allocating any dynamic memory the compiler generated one will work just fine, so, yes, you can leave it out. However, if you do include it in the class definition in the header file you need to implement it. Leaving it in, you could just add to Resistor.cpp:

1
2
3
Resistor::~Resistor()
{
}


2. Your constructor makes no sense. Instead of

1
2
3
4
5
6
7
8
9
Resistor::Resistor(double n, double t, string nm, bool display)
{
	nom = nom;
	tol = tol;
	name = name;
	if(display){
		cout<<"constructor was called"<<endl;
	}
}


I think you intended

1
2
3
4
5
6
7
8
9
Resistor::Resistor(double n, double t, string nm, bool display)
{
	nom = n;
	tol = t;
	name = nm;
	if(display){
		cout<<"constructor was called"<<endl;
	}
}


3. Resistor.cpp line 6
#include <string> was already included in Resistor.h
I am assuming that you are only including <iostream> in Resistor.cpp temporarily for testing purposes.

4. In Resistor.h using namespace std;
This statement pulls in the entire std namespace which is huge. Every future program that uses the Resistor class will include Resistor.h and hence pull in the whole std namespace. This defeats the whole purpose of having namespaces. Sooner or later this will cause a conflict of identifier names, which may be very difficult to track down. It is best to eliminate the using namespace std directive from the header file and instead fully qualify the names. For example,
std::string name; instead of string name and
std::string getName (bool display); instead of string getName (bool display);
Yes, you need an implementation for it, even if it's an empty implementation like

resistor::~resistor(){}

Just add this to your resistor.cpp after the last function.

Just so you know, when you declare a new class c++ will create a default constructor and destructor, but if you declare one you need to implement it to because c++ won't do that for you.
Last edited on
For the warning that not all paths return a value in Resister::getNom(),

1
2
3
4
5
6
7
8
double Resistor::getNom(bool display)
{
	
	if(display){
		cout<<"Set Nom was called"<<endl;
		return nom;
	}
}


If display is false then the body of the if statement is not executed and no value is returned. Move the return line outside of the if body.

1
2
3
4
5
6
7
8
double Resistor::getNom(bool display)
{
	
	if(display){
		cout<<"Set Nom was called"<<endl;
        }
	return nom;
}

Last edited on
You guys are awesome! Thank you. Yes I meant;


1
2
3
4
5
6
7
8
9
Resistor::Resistor(double n, double t, string nm, bool display)
{
	nom = n;
	tol = t;
	name = nm;
	if(display){
		cout<<"constructor was called"<<endl;
	}
}


And thank you for the clarification on the destructor. I added the coding to my Resistor.cpp file rather than let the program do one for me. With these small changes the program finally builds successfully! Again you guys are awesome I can't tell you how grateful I am to you guys.
Last edited on
Topic archived. No new replies allowed.