Binary Tree template, class specific function call - templates

Ok just a heads up, this is my first question on here so i apologize if I don't include every relevant piece of info on my first go, but I'll do my best.
My problem is with a specific function I'm trying to write in main() that will print out data from nodes if their "category" matches the category that is searched for. I'm likely just fumbling with syntax as I'm still pretty new at this. To be clear, the exact problem is that all the function calls I've tried tell me *****"No instance of Overloaded function "BinTree::inOrderTraverse [with Type=CategorizedContact]" matches the argument list. argument types are: (void). Object type is BinTree***** Here's the relevant main() code:
#include <iostream>
#include <string>
#include <stdexcept> //invalid_argument
using namespace std;
#include "name.h"
#include "contact.h"
#include "address.h"
#include "BinTree.h"
#include "BinNode.h"
#include "CategorizedContact.h"
#include "Field.h"
#include "htmlfunc.h"
using namespace AddressInfo;
void printMenu();
void printByCat(CategorizedContact&, int);
int getMenuInput();
int validateMenuInput(Field input);
Field printCategoryMenu();
Field categorySelection();
int main()
{
Address tmpAddress;
Name tmpName, tmpName2;
CategorizedContact tmpContact, tmpContact2, itemToRemove;
BinTree<CategorizedContact> myBook;
Field tmpString1, categoryIn;
int menuOption = 0, node = 0, count = 0, categoryMenuOption = 0, categoryInt = 0;
CategorizedContact& tmp = tmpContact2; // I was just experimenting with trying to initialize
//a ref variable here, to make the function call work.
myBook.readFile("address.csv");
do
{
printMenu();
menuOption = getMenuInput();
switch (menuOption)
{
case 1:
cout << "\t***** Add Contact *****\n\n";
categoryIn = categorySelection(); //Prints Category menu and gets input
tmpContact.setCategory(categoryIn); //Assigns category choice to tmpContact
cin >> tmpContact; //Gets the rest of the contact info
myBook.addItem(tmpContact); //Adds contact to address book
myBook.writeFile("address.csv", '\n'); //Writes new contact to file
break;
case 2:
cout << "\n\t***** Count Contacts *****\n";
count = myBook.getNumUsed();
cout << "Number of Contacts: " << count;
cout << endl << endl;
break;
case 3:
cout << "\n\t***** Print Contacts By Category *****\n";
categoryIn = printCategoryMenu(); //Prints category menu and gets choice
if (categoryIn == "All Contacts")
myBook.printAll();
categoryInt = stoi(categoryIn); // converts to int to match required function parameters
myBook.inOrderTraverse(printByCat(tmp, categoryInt));
break;
That last line before the break; is the function call I'm struggling with.
Here's it's declaration:
void printByCat(CategorizedContact& tmp, int categoryInt)
{
int count = 1;
switch (categoryInt)
{
case 65:
if (tmp.getCategory() == "Business")
cout << count << ". " << tmp << endl;
break;
default:
cout << "Error" << endl;
break;
}
}
It's unfinished, and probably not even designed correctly but I can't tell until i manage to get the function call working.
Lastly here's the relevant code from my inOrderTraverse .h and .tem files pertaining to the problem.
#ifndef BINTREE_H
#define BINTREE_H
#include <cstdlib> // NULL
#include <string>
#include <iostream> // cout
#include <fstream>
#include <algorithm> // copy
#include "BinNode.h"
#include "CategorizedContact.h"
#include "Contact.h"
template <class Type>
class BinTree
{
public:
BinTree();
BinTree(const BinTree<Type>& source);
~BinTree();
BinTree<Type>& operator=(const BinTree<Type>& source);//assignment operator
int getNumUsed() const { return(used); }
void addItem(Type dataIn);
void printAll();
void writeFile(string fileName, char delimeter = '\n');
void readFile(string fileName);
void inOrderTraverse(void process(Type&, int));
void debugOn() { debug = true; }
void debugOff() { debug = false; }
private:
bool debug;
int used;
BinNode<Type>* root;
void inOrderTraverse(void process(Type&, int),
BinNode<Type>* cursor, int& count);
void write(BinNode<Type>* cursor, char delimeter,
ofstream& outFile);
void printInOrder(BinNode<Type>* cursor, int& count);
void free(BinNode<Type>* cursor);
void copyTree(BinNode<Type>* cursor);
BinNode<Type>* alloc(Type itemToAdd);
};
#include "BinTree.tem"
And just the relevant .tem portions...
template <class Type>
void BinTree<Type>::inOrderTraverse(void process(Type&, int))
{
int count = 1;
inOrderTraverse(process, root, count);
}
template <class Type>
void BinTree<Type>::inOrderTraverse(void process(Type&, int),
BinNode<Type>* cursor, int& count)
{
if (cursor != NULL)
{
// In order traverse
inOrderTraverse(process, cursor->left, count);
// PROCESS
process(cursor->data, count);
count++;
inOrderTraverse(process, cursor->right, count);
}
}
Before anyone suggests changing the InOrderTraverse(void process(Type&, int)), or the overloaded version, just Know that I'm required to implement it that way for my project.
the only freedom i have is with ***printByCat(CategorizedContact, int)****, that can be changed as long as it's still compatible with inOrderTraverse.
So as i hope u can now see, the function in main() printByCat() is meant to take in a category from the user, and then serve as an argument itself for inOrderTraverse(printByCat()). but I'm obviously making a fundamental mistake that i don't understand.
At this point any guidance would be appreciated, I'm not asking anyone to do the coding for me as i know you are against that, but I really just need to understand why the function call isn't working. I'm guessing the problem stems from my lack of experience with reference variables, but The error I'm getting seems to suggest the function printByCat() which is being taken as an argument of inOrderTraverse, does not meet the argument requirements because it's not a void function, but it is a void function.... so yea I'm a little lost. Anyways thanks for your time, and please let me know if i forgot anything.

Found out what it was, apparently I can't include the arguments of printbyCat() when using this function as an argument of inOrderTraverse(), so the function call should have simply been: myBook.inOrderTraverse(printByCat).

Related

error: no matching function for call to "Queue::Queue()"

So I am trying to call a function in my main.cpp file but I get "error: no matching function for call to 'Queue::Queue()."
Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
class Queue
{
public:
Queue(int);
~Queue();
//circular queue methods
void enqueue(std::string);
std::string dequeue(); //should send through network, call transmit msg
void printQueue();
bool queueIsFull(); //send when full
bool queueIsEmpty(); //send when empty
protected:
private:
int queueSize;
int queueHead;
int queueTail;
int queueCount;
std::string *arrayQueue;
};
#endif // QUEUE_H
Queue.cpp
#include "Queue.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
Queue::Queue(int qs)
{
queueSize = qs;
arrayQueue = new string[queueSize];
queueHead = 0;
queueTail = 0;
}
Queue::~Queue()
{
delete[] arrayQueue;
}
void Queue::enqueue(string word)
{
for (int i=0;i<10;i++)
{
arrayQueue[i] = word;
}
}
void Queue::printQueue()
{
for(int j=0;j<10;j++)
{
cout<<arrayQueue[j]<<endl;
}
}
main.cpp
#include <iostream>
#include "Queue.h"
using namespace std;
int main()
{
int userChoice;
Queue q;
while(2==2)
{
cout<<"======Main Menu======"<<endl;
cout<<"1. Enqueue word"<<endl;
cout<<"2. Dequeue word"<<endl;
cout<<"3. Print queue"<<endl;
cout<<"4. Enqueue sentence"<<endl;
cout<<"5. Quit"<<endl;
cin>>userChoice;
if (userChoice == 1)
{
string enqueueWord;
cout<<"word: ";
cin>>enqueueWord;
enqueue(enqueueWord);
}
if (userChoice == 2)
{
}
if (userChoice == 3)
{
}
if (userChoice == 4)
{
}
if (userChoice == 5)
{
}
}
return 0;
}
So to call the function from the header file I did "Queue q;" at the beginning of the int main() and then when I needed to call the function I did "q.enqueue(enqueueWord)." I also tried just doing "Queue::enqueue(enqueueWord), but that also didn't work and I get a different error. I feel like this is an easy fix but I just can't figure it out. Thanks for the help and feel free to ask me to clarify anything.
Queue q;
attempts to call the default constructor Queue::Queue. However, this constructor has been removed automatically since you explicitly declare a constructor, namely Queue::Queue(int), on your own.
Pass an appropriate argument to q when initialized, like
Queue q1(42); // pre-C++11 syntax
Queue q{42}; // available since C++11
(Note: 42 is only an exemplary value here.)
You could also use default arguments to keep the definition as-is and initialize the object with a default value.
Notes:
Why while(2==2)? while (true) is the common way.

C++ Undeclared Identifier on Object creation

So I am new to c++, coming from C#. This is giving me several errors when compiling, which all seem to relate to this object declaration. Anyone able to show me the right way to do this?
I get an undeclared identifier where i declare tri(sideLength).
I have used this as a reference for object declaration, but it doesn't seem to be helping me.
Thanks.
#include <iostream> // Provides cout
#include <iomanip> // Provides setw function for setting output width
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cassert> // Provides assert function
#include <stdexcept>
#include <math.h>
using namespace std; // Allows all standard library items to be used
void setup_cout_fractions(int fraction_digits)
// Precondition: fraction_digits is not negative.
// Postcondition: All double or float numbers printed to cout will now be
// rounded to the specified digits on the right of the decimal.
{
assert(fraction_digits > 0);
cout.precision(fraction_digits);
cout.setf(ios::fixed, ios::floatfield);
if (fraction_digits == 0)
cout.unsetf(ios::showpoint);
else
cout.setf(ios::showpoint);
}
int main()
{
const int MAX_SIDE_LENGTH = 6;
const int INITIAL_LENGTH = 1;
const int DIGITS = 4;
const int ARRAY_SIZE = 6;
// Set up the output for fractions and print the table headings.
setup_cout_fractions(DIGITS);
// Each iteration of the loop prints one line of the table.
for (int sideLength = 0; sideLength < MAX_SIDE_LENGTH; sideLength += 1)
{
EquilateralTriangle tri(sideLength);
//Square sq(sideLength);
//Pentagon_Reg pent(sideLength);
//Hexagon_Reg hex(sideLength);
//Heptagon_Reg hept(sideLength);
//Octagon_Reg octa(sideLength);
cout << "Type: " << tri.Name() << "has area: " << tri.Area() << " with SideLength = " << sideLength;
}
return EXIT_SUCCESS;
}
//Template
class GeometricFigure
{
public:
GeometricFigure() { }
double SideLength;
virtual double Area() { return 0; };
virtual char* Name() { return ""; };
};
class EquilateralTriangle : public GeometricFigure {
public:
EquilateralTriangle(double sideLength)
{
SideLength = sideLength;
}
char* Name() { return "Equilateral Triangle"; }
double Area() { return (sqrt(3) / 2 * pow(SideLength, 2)); }
};
In C++, the compiler reads your code from top-to-bottom, once. This is a holdover from when early C compilers only had a few kilobytes of memory to work with - C was designed so that a compiler would only need to look at a little bit of the code at a time.
Because of this, things must have been declared or defined as necessary, before you try to use them.
Move both classes somewhere before main. GeometricFigure must be before EquilateralTriangle, and EquilateralTriangle must be before main.
You would need to "declare" or tell the compiler, where to look for the EquilateralTriangle and GeometricFigure, "before" you use it first. you might want to take a look at the similar discussion at - C# declarations vs definitions

using enum for an array index in c++

#include <stdlib.h>
#include <stdio.h>
using namespace std;
void main(){
char *resolutions[] = { "720x480", "1024x600", "1280x720", "1920x1080" };
int x = 0;
enum ResMode
{
p480,
p600,
p720,
p1080
};
ResMode res = p480;
printf("\nPlease enter the resolution you wish to use now by entering a number");
printf("\n480p[0], 600p[1], 720p[2], 1080p[3]");
gets(res);
printf("\nThe resolution you have selected is %s", resolutions[res]);
}
so basically i want to be able to press 1 and have it select p600 from enum and out put it as 1024x600 in the next line. I am getting a type conversion error.
How can i fix this?
Looks like you want to associate some items with other items. Usually associations are described in lookup tables or maps.
std::map<ResMode, std::string> map_table =
{
{p480, string("720x480")},
{p600, string("1024x600")},
{p720, string("1280x720")},
{p1080, string("1920x1080")},
};
int main(void)
{
cout << map_table[p480] << "\n";
return EXIT_SUCCESS;
}
Likewise, you can map menu selections to enums.
Edit 1
std::map<unsigned int, ResMode> selection_map =
{
{0, p480}, {1, p600}, {2, p720}, {3, p1080},
};
int main(void)
{
cout << "\n"
<< "Please enter the resolution you wish to use now by entering a number\n"
<<"480p[0], 600p[1], 720p[2], 1080p[3]";
unsigned int selection = 0;
cin >> selection;
if (selection < 4)
{
Resmode resolution_index = selection_map[selection];
cout << "You chose: "
<< map_table[resolution_index]
<< "\n";
}
return EXIT_SUCCESS;
}
int's are not implicitly convertible to an enum. You will have to read in an int and then cast it yourself. Example,
int resInt;
scanf("%d", &resInt);
res = static_cast<ResMode>(resInt);//Note that this does not do bound checking.
You can use "scanf" instead of "gets", something like this:
scanf("%d",&res); // I recommend use scanf_s
Or the iostream library with std::cin. But after taking the input, always, check if the input is the correct one.
As otehrs pointed out, there is no direct way of doing this. However, there are some recipes/tricks that you can use. I modified your code as follows:
#include <stdlib.h>
#include <stdio.h>
#define SOME_ENUM(DO) \
DO(_720x480) \
DO(_1024x600) \
DO(_1280x720) \
DO(_1920x1080)
#define MAKE_ENUM(VAR) VAR,
enum class RESOLUTIONS
{
SOME_ENUM(MAKE_ENUM)
};
#define MAKE_STRINGS(VAR) #VAR,
const char* const
RESOLUTION_NAMES[] =
{
SOME_ENUM(MAKE_STRINGS)
};
const char *
GET_RESOLUTION_NAME(RESOLUTIONS type)
{
return RESOLUTION_NAMES[static_cast<int>(type)];
}
int
GET_RESOLUTION_VALUE(RESOLUTIONS type)
{
return static_cast<int>(type);
}
RESOLUTIONS
GET_RESOLUTION(int i)
{
return static_cast<RESOLUTIONS>(i);
}
using namespace std;
int main(){
printf("\nPlease enter the resolution you wish to use now by entering a number");
printf("\n480p[0], 600p[1], 720p[2], 1080p[3]");
int res_type;
cin >> res_type;
RESOLUTIONS selected_res = GET_RESOLUTION(res_type);
printf("\nThe resolution you have selected is %s\n\n", GET_RESOLUTION_NAME(selected_res));
return 0;
}
Sorry for not providing an explanation, as I have to go now. This recipe can be found here. The code works and compiles for c++11.

Matching constructor not found (C++) in HardwareStore Class

I have been working on a hardware store application, where there is a HardwareRecordclass that stores information about each object in a store (ex: nuts, bolts, screws, and so forth).
The information is stored in a ".dat" file, but this is not important right now.
Here's my declaration of this class:
// Definition of HardwareRecord class
#ifndef __Initialize_Hardware_Store_File__HardwareRecord__
#define __Initialize_Hardware_Store_File__HardwareRecord__
#include <iostream>
class HardwareRecord
{
public:
HardwareRecord(const int& account=0,const std::string& name="",const std::string& description="",const double& price=0.0); //constructor
HardwareRecord operator=(HardwareRecord&);
//'set' and 'get' functions
void setAccountNumber(int);
int getAccountNumber() const;
void setName(std::string);
std::string getName() const;
void setPrice(double);
double getPrice() const;
void setDescription(std::string);
std::string getDescription() const;
void wipeRecord(); //set everything to blank
private:
int myAccountNumber;
std::string myName;
std::string myDescription;
double myPrice;
};
#endif /* defined(__Initialize_Hardware_Store_File__HardwareRecord__) */
Here's my class definition:
// Implementation of HardwareRecord class definition
#include <iostream>
#include "HardwareRecord.h"
using namespace std;
HardwareRecord HardwareRecord::operator=(HardwareRecord & aRecord)
{
this->myAccountNumber=aRecord.myAccountNumber;
this->myName=aRecord.myName;
this->myDescription=aRecord.myDescription;
this->myPrice=aRecord.myPrice;
return *this; //allow for cascaded overloading
}
HardwareRecord::HardwareRecord(const int& account,const string& name,const string&
description,const double& price)
{
setAccountNumber(account);
setName(name);
setPrice(price);
setDescription(description);
}
void HardwareRecord::wipeRecord()
{
setAccountNumber(0);
setName("");
setPrice(0);
setDescription("");
}
void HardwareRecord::setAccountNumber(int num)
{
if (num < 0)
{
throw invalid_argument("The account number is not in the valid range (greater or equal to 0)");
}
else
{
myAccountNumber=num;
}
}
int HardwareRecord::getAccountNumber() const
{
return myAccountNumber;
}
void HardwareRecord::setName(string name)
{
myName=name;
}
string HardwareRecord::getName() const
{
return myName;
}
void HardwareRecord::setPrice(double price)
{
if (price < 0)
{
throw invalid_argument("The price can not be less than zero");
}
else
{
myPrice=price;
}
}
double HardwareRecord::getPrice() const
{
return myPrice;
}
void HardwareRecord::setDescription(string description)
{
this->myDescription=description;
}
string HardwareRecord::getDescription() const
{
return myDescription;
}
The class described is supposed to be used in the following main.cpp file:
// Application that models a store's record of inventory
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <sstream>
#include "HardwareRecord.h" //HardwareRecord definition
using namespace std;
//enumeration of choices
enum Choices {WIPE_RECORDS,UPDATE,LIST,PRINT,DELETE,NEW,END,LAST};
std::ostream& operator<<(std::ostream& op,const Choices& choices)
{
//print the string corresponding to the value of enum type Choices
string output="";
switch (choices)
{
case WIPE_RECORDS:
output = "wipe records";
break;
case UPDATE:
output = "update records";
break;
case LIST:
output = "list records";
break;
case PRINT:
output = "print records";
break;
case DELETE:
output = "delete records";
break;
case NEW:
output = "add new record";
break;
case END:
output = "terminate application";
break;
case LAST:
output = "an option used to iterate over the values in the Choice enumeration";
break;
default:
cerr << "Error. invalid value is read";
exit(EXIT_FAILURE);
break;
}
op << output; //print output
return op;
}
//prototype of helper functions
int enterChoice();
void wipeRecords(fstream&);
void updateRecord(fstream&);
void listRecords(fstream&);
void createTextFile(fstream&);
void deleteRecord(fstream&);
void newRecord(fstream&);
int main()
{
//open file for reading and writinbg
fstream outRecord ("HardwareRecord.dat",ios::in|ios::out|ios::binary);
//exit program if fstream cannot open file
if (!outRecord)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
}
int choice; //user's choice
//enable user to specify action
while ((choice=enterChoice()) !=END)
{
switch (choice)
{
case WIPE_RECORDS: //wipe all records clean
wipeRecords(outRecord);
break;
case UPDATE: //update a record
updateRecord(outRecord);
break;
case LIST: //list all current records
listRecords(outRecord);
break;
case PRINT: //print a record
createTextFile(outRecord);
break;
case DELETE: //delete a record
deleteRecord(outRecord);
break;
case NEW: //add a new record (if space allows)
newRecord(outRecord);
break;
default: //display error if user does not select valid choice
cerr << "Incorrect choice" << endl;
}
outRecord.clear();
}
return 0;
}
//enable user to input menu choice
int enterChoice()
{
//display avaliable options
cout << "\nEnter your choice:\n"<< endl;
Choices aChoice;
for (int c=WIPE_RECORDS; c < LAST; c++)
{
aChoice= (Choices) c;
cout << c << " - " << aChoice << endl;
}
cout << "\n?: ";
int menuChoice;
cin >> menuChoice;
return menuChoice;
}
void wipeRecords(fstream& theFile)
{
HardwareRecord temp;
for (int i=0; i < 100;i++)
{
//convert record from binary and assign to temp
//make temp "wipe itself"
}
}
Yes, I realize that many of the functions are defined by prototype, but are not actually declared. This will be done later after this very problem described shortly afterwards is fixed. Please direct your attention to the following piece of code, from this very file:
void wipeRecords(fstream& theFile)
{
HardwareRecord temp; //Here's where the error occurs: No Matching constructor!
for (int i=0; i < 100;i++)
{
//convert record from binary and assign to temp
//make temp "wipe itself"
}
}
Whenever I try to compile this project on my Mac (I use xCode), I get the following error for the line that is commented. The error is "No matching constructor for initialization of 'HardwareRecord'". However, I provide default values for the constructor of a HardwareRecord object, so the line
HardwareRecord temp;
should initialize without any problems.
What is going on? How can I fix this?
I think this is the problem. In your constructor, you use an std::string&, however, you never include <string> in your code!
Along with some other errors, compiling with G++ gives you:
prog.cpp:46:57: error: ‘string’ does not name a type
This may invalidate your default constructor.
HardwareRecord class should have default constructor, e.g., like this:
class HardwareRecord {
public:
HardwareRecord() : myAccountNumber(0),
myName(""),
myDescription(""),
myPrice(0.0f) {}
...
};
Your current constructor with default parameter values doesn't seem to be regarded as a 'Default Constructor'.
You're attempting to use a default constructor.
HardwareRecord temp;
But you've declared a constructor that takes arguments, as well as an assignment operator. The act of declaring a constructor that takes arguments means that the compiler will not generate a default constructor for you. So if you want one you'll have to declare one yourself OR use the constructor you've created.
EDIT
My answer above is NOT correct as the OP has provided defaults for all specified arguments.
In the case I specified the compiler will state something like:
error: no matching function for call to ‘Foo::Foo()’
But with defaults specified it will compile.
Small test:
-- foo.h
class Foo
{
private:
int _i;
public:
Foo( int i );
};
-- foo.cpp
#include "foo.h"
Foo::Foo( int i )
: _i( i )
{
}
int main()
{
Foo foo;
return 0;
}

scope error message

Hey guys, just learning about composition of classes and ran into this error.
Gradebook.h
#ifndef GRADEBOOK_h
#define GRADEBOOK_h
#include "StudentRec.h"
#include <iostream>
#include <string>
class GradeBook
{
public:
GradeBook();
GradeBook(string initLastName, int studGrades);
void AddStudent(string initLastName, int studGrades);
void ShowStudents();
void UserInterface();
private:
static const int numStudents=20;
StudentRec student[numStudents];
static int studentCounter;
static int gradeCounter;
};
#endif
Gradebook.cpp
#include "Gradebook.h"
#include "StudentRec.h"
#include <iostream>
#include <string>
using namespace std;
GradeBook::GradeBook()
{}
GradeBook::GradeBook(string initLastName, int studGrades)
{}
void GradeBook::AddStudent(string initLastName, int studGrades)
{
gradeCounter++; //Increments variable responsible for tracking # of grades per student
StudentRec newStudent(initLastName, studGrades); //creates new student object
student[studentCounter]=newStudent; //Assigns new student object to array
studentCounter++; //Increments variable responsible for tracking # of students
}
void GradeBook::ShowStudents()
{
for(int i=0;i<studentCounter; i++){ //Displays information for each student instance
cout<<student[i].GetLastName()<<' ';
for(int j=0; j<gradeCounter; j++)
cout<<student[i].GetGrades(j)<<' ';
cout<<endl;
}
}
void GradeBook::UserInterface()
{
char choice=' ';
string studLastName;
int studGrade;
cout<<"Welcome to GradeBook, this program stores students"
<<" grades by last name. To ADD a student press the 'A'"
<<" key. To LIST all students, press the 'L' key. To "
<<" QUIT, press the 'Q' key."<<endl<<endl;
cin>>choice;
choice=toupper(choice);
while(choice!='Q')
{
if(choice='A'){
cout<<"To add a student, please enter their last name"
<<" followed by a space and a non-negative grade"
<<" Ex. McClure 96";
cin>>studLastName>>studGrade;
AddStudent(studLastName, studGrade);
}
else if(choice='L'){
cout<<"This is a list of all students in GradeBook"
<<endl<<endl;
ShowStudents(); //Displays all StudentRec objects
}
else if(choice!='Q')
cout<<"Please enter another letter"<<endl;
cout<<"To ADD a student press the 'A' key. To LIST all students, press the 'L' key. To "
<<" QUIT, press the 'Q' key."<<endl<<endl;
}
}
Main.cpp
#include <iostream>
#include <string>
#include "StudentRec.h"
#include "Gradebook.h"
using namespace std;
int main()
{
GradeBook gradeBook;
UserInterface();
return 0;
}
StudentRec.cpp
#include <iostream>
#include <string>
#include "StudentRec.h"
using namespace std;
StudentRec::StudentRec()
{
lastName=" ";
for(int i=0;i<numGrades; i++)
grades[i]=0;
}
StudentRec::StudentRec(string initLastName, int studGrade)
{
static int gradeCounter=0;
lastName=initLastName;
grades[gradeCounter]=studGrade;
}
string StudentRec::GetLastName()
{
return lastName;
}
int StudentRec::GetGrades(int gradeNum)
{
return grades[gradeNum];
}
void StudentRec::AddGrades(int studGrade)
{
gradeCounter++;
if(gradeCounter<=numGrades)
grades[gradeCounter]=studGrade;
else
cout<<"Too many grades for this student";
}
StudentRec.h
#ifndef STUDENTREC_h
#define STUDENTREC_h
#include <iostream>
#include <string>
using namespace std;
class StudentRec
{
public:
StudentRec();
StudentRec(string initLastName, int studGrade);
string GetLastName();
int GetGrades(int gradeNum);
void AddGrades(int studGrade);
private:
static const int numGrades=10;
static int gradeCounter;
string lastName;
int grades[numGrades];
};
#endif
In the Main.cpp file, I get an error I can't find the solution for. It reads
error: "UserInterface" was not declared in this scope. I got this error while compiling in XCode
I got error C3861: 'UserInterface': identifier not found
Obviously i've tried it in two IDEs, I also have the StudentRec.cpp and .h, but not sure you need them. Thanks in advance for the help
It appears that UserInterface() is actually a member function of GradeBook, correct?
If so, you need to add a declaration for the member function in the GradeBook class declaration:
class GradeBook
{
public:
GradeBook();
GradeBook(string initLastName, int studGrades);
void AddStudent(string initLastName, int studGrades);
void ShowStudents();
void UserInterface(); // Added
// ...
private:
// ...
};
This way, the compiler will "know" that the UserInterface() function exists as a member function. You then provided the definition in void GradeBook::UserInterface() in your .cpp file.
Then you need to call it on a GradeBook instance, like the gradeBook variable in your main() function:
int main()
{
GradeBook gradeBook;
// This calls the member function UserInterface() on the gradeBook variable.
gradeBook.UserInterface();
// This calls the global UserInterface(), which doesn't exist.
// UserInterface();
return 0;
}
UserInterface() is a method of GradeBook. The call probably needs to be:
gradeBook.UserInterface();