<insert name of struct> was not declared in this scope - c++

http://pastebin.com/4gvcQm7P
#include <iostream>
using namespace std;
int GenerateID()
{
static int nextID = 0;
return nextID++;
}
void PrintInformation(Employee EmployeeName)
{
cout << EmployeeName << "'s ID is: " << EmployeeName.ID << endl;
cout << EmployeeName << "'s age is: " << EmployeeName.age << endl;
cout << EmployeeName << "'s wage is: " << EmployeeName.wage << endl;
}
int main()
{
struct Employee
{
int ID;
int age;
float wage;
};
Employee Dominic;
Employee Jeffrey;
Dominic.ID = GenerateID();
Dominic.age = 22;
Dominic.wage = 7.10;
Jeffrey.ID = GenerateID();
Jeffrey.age = 28;
Dominic.wage = 7.10;
PrintInformation(Dominic);
PrintInformation(Jeffrey);
return 0;
}
/*
C:\CBProjects\Practise\main.cpp|11|error: variable or field 'PrintInformation' declared void|
C:\CBProjects\Practise\main.cpp|11|error: 'Employee' was not declared in this scope|
C:\CBProjects\Practise\main.cpp||In function 'int main()':|
C:\CBProjects\Practise\main.cpp|39|error: 'PrintInformation' was not declared in this scope|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 0 seconds) ===|
*/
The above pastebin link shows the code I used and the build report. Following this report I attempted to forward declare the struct without including members and then there is an 'incomplete type' error.
What is the solution?
Edit: I'm using c++11
Edit 2: Here is what happens if I try to forward declare the struct, including the members:
http://pastebin.com/rrt4Yjes#

There are two solutions: Make Employee a non-local class/struct or make PrintInformation a template. For the first solution, just move Employee before PrintInformation. The second solution would be:
template< typename Employee >
void PrintInformation(const Employee& EmployeeName)
{
cout << " EmployeeName's ID is: " << EmployeeName.ID << endl;
cout << " EmployeeName's age is: " << EmployeeName.age << endl;
cout << " EmployeeName's wage is: " << EmployeeName.wage << endl;
}
Note that in any case you don't want a copy of Employee just to print some information, hence make the parameter of PrintInformation a constant reference as shown above.

First piece of information in the error is the line number.
C:\CBProjects\Practise\main.cpp|11|error: variable or field 'PrintInformation' declared void|
Line 11. Lets look at line 11.
void PrintInformation(Employee EmployeeName)
This all looks valid, but what's an Employee? We don't find that out until line 21. Your function, PrintInformation wants to make use of the internal plumbing of PrintInformation so the function actually needs to know the full definition of the struct/class.
In addition to all this, you have very explicitly made Employee a private type of main by defining it inside the function. What you are actually declaring is main::Employee.
A few solutions:
Declare "Employee" in the same scope as PrintInformation, i.e. at the global scope at the top of the file after the includes etc.
Or make "PrintInformation" a member function of Employee.
struct Employee
{
void PrintInformation()
{
std::cout << " Employee's ID is: " << ID << '\n';
std::cout << " Employee's age is: " << age << '\n';
std::cout << " Employee's wage is: " << wage << '\n';
}
...
};
...
Dominic.PrintInformation();
Or implement operator<< (probably advanced for where you are right now).
I'd also like to point out an aspect of style that is lining you up for some serious headaches down stream: You're using the same UpperCamelCase for variables and types, but being inconsistent with types. It's going to benefit you if you teach yourself to prefix member variables with something and maintain consistent case early on:
struct Employee // UpperCamel for types.
{
int m_id;
int m_age;
float m_wage;
};
It now becomes very easy to separate local variables and types and member variables. This is going to become especially useful as you start to learn about member functions.
struct Employee // UpperCamel for types.
{
int m_id;
std::string m_name;
int m_age;
float m_wage;
Employee(const std::string& name, int age, float wage)
: m_id(nextID++)
, m_name(name)
, m_age(age)
, m_wage(wage)
{}
...
};

You should declare struct Employee before using it in PrintInformation() or make PrintInformation a template (as #DanielFrey did).
Fix your PrintInformation() to following as you cannot directly print a struct data unless you overloading << for the struct (check out here on how to do this).
void PrintInformation(Employee EmployeeName)
{
cout << " EmployeeName's ID is: " << EmployeeName.ID << endl;
cout << " EmployeeName's age is: " << EmployeeName.age << endl;
cout << " EmployeeName's wage is: " << EmployeeName.wage << endl;
}

Related

(C++) Vector elements seem to disappear after for loop ends

I'm extremely new to C++ (even newer to OOP) and I'm doing my first project that doesn't take place within one .cpp file. I've run into a seemingly simple issue where my vector data seems to be disappearing.
Code chunk inside main.cpp's main function:
vector<Horse> HorseStable(horseAmount); // creating an vector of horse objects based on user input horseAmount
for (int i = 0; i < horseAmount; i++) // sets name for each horse and rider
{
string nameString = "";
string riderString = "";
cout << "Enter name for horse #" << (i + 1) << ": ";
cin >> nameString;
HorseStable[i].setName(nameString);
cout << "Enter name for rider of " << nameString << ": ";
cin >> riderString;
HorseStable[i].setRider(riderString);
system("cls");
}
HorseStable[0].printName(); // a test to see if the horse name stayed inside the vector (it did not)
Entire Horse.h file:
#pragma once
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
class Horse
{
private:
std::string name;
std::string rider;
public:
// these three ints were supposed to be private, but I couldn't access
// maxRunningDistPerSecond as a displayHorse() function parameter from main
// maybe figuring out my first issue will help with this, as I was attempting
// HorseStable[0].displayHorse(maxRunningDistPerSecond)
int maxRunningDistPerSecond;
int distanceTraveled;
int racesWon;
Horse() // default constructor
{
std::string name = " ";
std::string rider = " ";
int maxRunningDistPerSecond = 100;
int distanceTraveled = 0;
int racesWon = 0;
};
int runASecond(int, int);
int sendToGate(int);
void displayHorse(int);
std::string setName(std::string); // sets the horse name based on user input from main.cpp variable
std::string printName(); // simply prints the horse name, I don't believe my issue is here
std::string setRider(std::string);
std::string printRider();
};
Code chunk inside Horse.cpp:
std::string Horse::setName(std::string nameString) // takes user input for horse name
{
Horse::name = nameString;
return std::string(nameString);
}
std::string Horse::printName() // prints the horse's name
{
return std::string(name);
}
setName() and getName() work perfectly within my for loop inside main.cpp, but all data seems to disappear when I attempt them after the loop ends. I've looked for hours for solutions, but had to revert to this stable build after nothing worked. I'm not very good with pointers and passing by reference, but these seem to be the only things that will work. Is it possible that I was using pointers wrong? Should I be creating a vector of Horse pointers, rather than a vector of actual Horse objects?
My other issue:
If you've noticed my public members that are supposed to be private in Horse.h, I cannot access them when private as parameters from functions called in main. This makes some sense, as my function call in main looked like this:
HorseStable[0].displayHorse(distanceTraveled)
I'm not sure how I could refer to each element of the vector within the Horse class, which seems like the only way distanceTraveled would be reachable as private. My professor wants the variables in question to be private, which makes this an issue. The user defines the amount of Horse objects, which means I can't just declare a few named Horses and simply displayHorse(distanceTraveled) them.
Function declaration from Horse.cpp:
void Horse::displayHorse(int distanceTraveled) // attempts to show a graphic of the race progress
{
if (distanceTraveled >= 50)
{
std::cout << "|-> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 100)
{
std::cout << "|--> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 150)
{
std::cout << "|---> |" << " " << name << ", ridden by " << rider;
} // this goes on up to 1000, but this is all that's necessary for posting
I apologize if my formatting isn't up to par, but this assignment has really been stressing me out. I've been understanding all the new material, but it always seems like pointers and referencing are the things that render my assignments unusable.

How to carry over information in variable from using a void

I am a new coder and I am just messing around with functions and testing variables where I got stuck. My goal is to make a function that when you input your name and age it will say "Hello (name) You are (age)" x3 with 3 different names and ages. At the end the program will say "Hello (name1) (name 2) (name 3)" I got everything to work except for the last part and having the names information carry over. How does one do that. (I use C++)
#include <iostream>
using namespace std;
void whatisName(string name, int age)
{
cout << "What is thy name: " << endl;
cin >> name;
cout << "What is thy age: " << endl;
cin >> age;
cout << "Hello " << name << " You are " << age << endl;
}
void allNames(string name1, string name2, string name3 )
{
cout << "Hello " << name1 << " " << name2 << " " << name3 << " " << endl;
}
int main()
{
string myName, myName2, myName3;
int myage, myage2, myage3;
whatisName(myName, myage);
whatisName(myName2, myage2);
whatisName(myName3, myage3);
allNames (myName, myName2, myName3);
}
Pass your variables by reference.
Change:
void whatisName(string name, int age) { ..
to:
void whatisName(string& name, int& age) { ...
As said above Passing by reference is your best bet. The reason you would want to pass by reference is because your parameter may change after you exit the function. If you don't pass by reference then your parameter will not change when you exit the function
void whatisName(string name, int age){...}
this won't change the parameter name or the integer age. So if I put in
string a = "foo";
int b = 16;
whatisName(a,b)
No matter what happens inside the function a = "foo" and b = 16. Because we haven't created the function to pass by reference. To fix that we go to the function declaration and change it like
whatisName(string &name,int& age)
This will now change it so that the parameters inside that function can be modifiable.

how can a void function be called to the main, if there are no returns?

I wanted to create a function that retrieves all the information from previous functions within the same Class, and prints the values that were returned in the format of a bunch of cout statements, there is nothing for me to return in this PrintStatement() function, so I would create a void function, correct? My issue is in the int main(), I cannot cout a void function.
this is my account header file, and the function piece from my account.cpp file.
class Account {
public:
//Object constructor
Account(char firstName[], char lastName[], char sinNumber[], double balance, int accountType, int transactions);
//Object operations
double DepositAmt(double amount);
double WithdrawAmt(double amount);
void PrintStatement();
double getFinalBalance(double fbal);
string getAccountType();
double getTransactions (double Deposit, double Withdraw);
private:
//Object properties
char firstName[255];
char lastName[255];
char sinNumber[255];
double balance;
int accountType;
int transactions;
};
void Account::PrintStatement()
{
cout << "First Name: " << firstName << endl;
cout << "Last Name: " << lastName << endl;
cout << "SIN Number: " << sinNumber << endl;
cout << "Account Type: " << accountType << endl;
cout << "Final Balance: " << balance << endl;
cout << "Transactions: " << transactions << endl;
};
the global variables have already been initialized.
What I've tried:
I originally tried to cout << account.PrintStatement() << endl; however I get an error C2679 (binary '<<' : no operator found which takes a right-hand operand of type 'void' (or there is no acceptable conversion)
I thought maybe changing things to apply to a string function instead would work, but instead I get a bunch of int conversion errors etc.
I'm unsure of what to do.
I am required to put these in a function just to be clear.
I tried using this question https://stackoverflow.com/questions/12766858/how-to-call-void-function-from-main to help me, it made sense that the poster was using a reference, but I do not have that. Is there another way?
I originally tried to cout << account.PrintStatement() << endl;
Well, the expression account.PrintStatement() is abject nothingness because the function has a void return type. As you've indicated, the function returns nothing, so there is nothing to stream to cout.
The function itself has already streamed a bunch of stuff to cout, fulfilling all your couty needs. So, simply invoke it:
account.PrintStatement();
That's it!
Just call the method on your instance of the class. It doesn't need to return anything; it will do the counts you want and then return to main.
When we use cout<<something_here, the compiler will interpret it as "print the value of something_here". Now, something_here can be a lot of things. When it is a function, cout will print the value returned by the function. In your case, the return type is void i.e. nothing. So, there is nothing to print.
To fix your issue, you can directly call account.PrintStatement(); since you have already printed what you wanted to print inside this function.

C++ Can't figure out output for a class that holds player information. It outputs garbage

I've been pulling my hair out trying to figure out this program. The class has to hold 3 player's info and output their info. My output function is not outputting from my set/get functions. Also, if I output the array indexes the program crashes (that's the array indexes are commented out in the Output function).
edit: I'll just show one profile to keep the code smaller
Any help is appreciated.
#include <cstdlib>
#include <iostream>
using namespace std;
class PlayerProfile
{
public:
void output();
void setName1(string newName1); //player's name
void setPass1(string newPass1); //player's password
void setExp1(int newExp1); //player's experience
void setInv1(string newInv1[]); //player's inventory
void setPos1(int newX1, int newY1); //player's position
string getName1();
string getPass1();
int getExp1();
string getInv1();
int getPos1();
private:
string name1;
string pass1;
int exp1;
string inv1[];
int x1;
int y1;
};
int main(int argc, char *argv[])
{
PlayerProfile player;
cout << "This program generates three player objects and displays them." << endl;
cout << endl;
player.output();
system("PAUSE");
return EXIT_SUCCESS;
}
void PlayerProfile::setName1(string newName1)
{
newName1 = "Nematocyst";
name1 = newName1;
}
void PlayerProfile::setPass1(string newPass1)
{
newPass1 = "obfuscator";
pass1 = newPass1;
}
void PlayerProfile::setExp1(int newExp1)
{
newExp1 = 1098;
exp1 = newExp1;
}
void PlayerProfile::setInv1(string newInv1[])
{
newInv1[0] = "sword";
newInv1[1] = "shield";
newInv1[2] = "food";
newInv1[3] = "potion";
inv1[0] = newInv1[0];
inv1[1] = newInv1[1];
inv1[2] = newInv1[2];
inv1[3] = newInv1[3];
}
void PlayerProfile::setPos1(int newX1, int newY1)
{
newX1 = 55689;
x1 = newX1;
newY1 = 76453;
y1 = newY1;
}
string PlayerProfile::getName1()
{
return name1;
}
string PlayerProfile::getPass1()
{
return pass1;
}
int PlayerProfile::getExp1()
{
return exp1;
}
string PlayerProfile::getInv1()
{
return inv1[0], inv1[1], inv1[2], inv1[3];
}
int PlayerProfile::getPos1()
{
return x1, y1;
}
void PlayerProfile::output()
{
cout << "Player Info - " << endl;
cout << "Name: " << name1 << endl;
cout << "Password: " << pass1 << endl;
cout << "Experience: " << exp1 << endl;
cout << "Position: " << x1 << ", " << y1 << endl;
cout << "Inventory: " << endl;
/*cout << inv1[0] << endl;
cout << inv1[1] << endl;
cout << inv1[2] << endl;
cout << inv1[3] << endl; */
}
This is the output that I am getting:
This program generates three player objects and displays them.
Player Info -
Name:
Password:
Experience: -2
Position: 3353072, 1970319841
Inventory:
Press any key to continue . . .
I'm sorry if I sound like an idiot, this is the first time I have programmed with classes and I am very confused.
First:
You do not have a constructor declared or defined in your class so when you compile, the compiler provides you with a default constructor.
The line
PlayerProfile player;
calls the default constructor provided by the compiler. This default constructor only allocates memory for your class member variables, but does not set their values. This is why name1, pass1, exp1, x1, y1 are not outputting what you expect.
Second:
C++ will not call get or set functions for you, and I think you are misunderstanding how c++ functions work.
this
void PlayerProfile::setName1(string newName1)
{
name1 = newName1;
}
is a function definition. You do not need to assign newName1 inside the function. It's value is passed to the function when a line like
setName1("Nematocyst");
is executed.
If you write a constructor, you can use it to call your set functions, and pass them the values you want to set member variables to.
If you do not want to write a constructor, you can call class functions/methods from main with:
player.setName1("Nematocyst");
Third:
Your program crashes because you are not using arrays properly. Here is a tutorial on how to declare an array and access it's contents.
Generally, I think you are trying to run before you know how to walk. Try not to get frustrated. Learn how arrays work, how functions work, and then how classes work. I hope this is not your homework assignment!

C++ multilevel inheritance

I have made a program where there are three classes, each one inherits from one another but when I try to make a derived class function, the cout gives me an error such as this
3 IntelliSense: no suitable user-defined conversion from "std::basic_ostream<char, std::char_traits<char>>" to "std::string" exists e:\Visual Studio Projects\test\test\Source.cpp 19 10 test
What am I suppose to change and what would be the solution. Also if your could point out my mistake that would be nice
#include<iostream>
#include <string>
std::string name;
class Base{
public:
void getRed(){
std::cout << "Your name is : " << name << std::endl;
}
};
class Boy:public Base{
public:
Boy(){
name = "john";
}
std::string newInf(){
return std::cout << "Boy2 name is: " << name << std::endl;
}
};
class Boy2: public Boy{
public:
Boy2(){
name = "Mike";
}
};
int main(){
Boy boy;
boy.getRed();
Boy2 boy2;
boy2.newInf();
system("pause");
return 0;
}
Your compile error is not related to multilevel inheritance.
std::string newInf(){
return std::cout << "Boy2 name is: " << name << std::endl;
}
This is wrong. std::cout << "Boy2 name is: " << name << std::endl is, well... a kind of std::basic_ostream & and you cannot convert it into std::string.
This should be OK, just like you wrote getRed().
void newInf(){
std::cout << "Boy2 name is: " << name << std::endl;
}
you defined newInf() as a function that returns std::string,
where you are actually returning std::cout which is ostream .
so in run time it tries to convert ostream to string, and fails, that's why you get the message:
no suitable user-defined conversion from "std::basic_ostream>" to "std::string" exists