Can't Include function definitions into another source file [duplicate] - c++

This question already has answers here:
duplicate symbol error C++
(4 answers)
How do I use extern to share variables between source files?
(19 answers)
Closed 2 years ago.
Good Evening Everyone,
I'm taking a c++ class right now, and the teacher wants me to include the function definitions into another main. Every time that I do however, I get this error:
Severity Code Description Project File Line Suppression State
Error LNK2005 "unsigned int speed" (?speed##3IA) already defined in Sourcjhkhje.obj Project4 C:\Users\muhammad\source\repos\Project4\Project4\TestBicycle.obj 1
Severity Code Description Project File Line Suppression State
Error LNK1169 one or more multiply defined symbols found Project4 C:\Users\muhammad\source\repos\Project4\Debug\Project4.exe 1
All I need to do is move the function definitions into one source, and the main into another. Anyone know what's causing this issue?
These are what my files look like.
header 1:
#pragma once
size_t speed(0);
size_t GetSpeed();
const size_t MINspeed(10);
const size_t MAXspeed(40);
header 2:
#pragma once
#include <iostream>
#include <iomanip>
using namespace std;
header 3:
#include "BicycleLibIncludes.h"
void SetSpeed(size_t sp);
void DefaultSetSpeed(size_t s);
void DistanceTravelled(size_t x);
size_t GetSpeed();
size_t GetMinSpeed();
size_t GetMaxSpeed();
void GetSelectedSpeed();
source 1:
#include "BicycleLibIncludes.h"
#include "BicyclePrototypes.h"
/*void SetSpeed(size_t sp)
{
//cout << "Enter the current speed:";
//cin >> sp;
if ((sp >= 10) && (sp <= 40))
{
speed = sp;
}
else
{
cout << "This value is too high/low!";
}
}*/
size_t GetSpeed()
{
return (speed);
}
size_t GetMinSpeed()
{
return size_t(MINspeed);
}
size_t GetMaxSpeed()
{
return size_t(MAXspeed);
}
void DefaultSetSpeed(size_t s = 20)
{
speed = s;
}
void GetSelectedSpeed()
{
string speedunit;
while (true)
{
cout << "Enter M or K for mph or kmh respecitvely. Hit anything else to quit.";
cin >> speedunit;
if (speedunit == "M" || speedunit == "K")
{
break;
}
else
{
continue;
}
}
if (speedunit == "M")
{
cout << speed;
}
if (speedunit == "K")
{
double toKmPerHour = 1.61;
double speedinKmPerHour = speed * toKmPerHour;
cout << speedinKmPerHour << "\n";
std::cout << setprecision(3) << speedinKmPerHour << "\n";
cout << static_cast<int>(speedinKmPerHour) << "\n";
cout << static_cast<int>(speedinKmPerHour + 0.5) << "\n";
cout << floor(speedinKmPerHour) << "\n";
cout << ceil(speedinKmPerHour) << "\n";
}
}
void DistanceTravelled(size_t x)
{
static size_t accessCounter;
static int s;
cout << "Total distance for all trips so far: " << s << "\n";
s += x;
cout << "distance travelled for this trip was:" << x;
cout << "\nTotal distance for all trips so far: " << s << "\n";
s += x;
accessCounter++;
cout << "Number of times you've used this program:" << accessCounter;
}
int main()
{
DefaultSetSpeed();
cout << GetSpeed() << "\n";
DefaultSetSpeed(28);
cout << GetSpeed() << "\n";
cout << "Enter the speed you want to set:";
size_t userinput;
cin >> userinput;
SetSpeed(userinput);
cout << "Current Speed = " << GetSpeed()
<< "\nMAXspeed = " << GetMaxSpeed()
<< "\nMINspeed = " << GetMinSpeed() << "\n";
system("pause");
system("cls");
GetSelectedSpeed();
cout << "First trip:\n";
DistanceTravelled(5);
cout << "\nSecond trip:\n";
DistanceTravelled(10);
cout << "\nThird trip:\n:";
DistanceTravelled(15);
}
source 2: (Just did this one as a test)
#include "BicycleLibIncludes.h"
#include "BicyclePrototypes.h"
void SetSpeed(size_t sp)
{
//cout << "Enter the current speed:";
//cin >> sp;
if ((sp >= 10) && (sp <= 40))
{
speed = sp;
}
else
{
cout << "This value is too high/low!";
}
}
Thank you.

Related

Sorting a Class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
So, I am learning about classes in C++, I created two classes, one for a University that contains a list of class Students, i managed to create students, and introduce some values to the classes, but now i want to sort the class students by student number, i tryed using the sort function, but im not succeeding. I will leave my code bellow, please give some good tips and advises, so I can improve my code. thanks
main.css
#include <iostream>
#include "university.h"
#include "students.h"
using namespace std;
int main() {
university univ = university();
return 0;
}
university.h
#pragma once
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include "students.h"
using namespace std;
class university
{
private:
list<students> lstudents;
list<students>::iterator itstudents;
public:
university();
void setStudents(list<students> lstudents);
void registerStudent();
void list();
void average();
//void sortstudents();
};
university.cpp
#include "university.h"
using namespace std;
university::university() { //constructor
string resp = "s";
int op;
bool out = true;
cout << "Enter Students:" << endl;
while (resp != "n")
{
this->registerStudent();
cout << "Continue inserting? (s/n)" << endl;
cin >> out;
cin.ignore();
}
while (out)
{
cout << "What you Want to do? (1- List Students 2- Sudent Average 3- Sort Students by Number 4- Leave)" << endl;
cin >> op;
switch (op)
{
case 1:
this->list();
break;
case 2:
this->average();
break;
/*case 3:
this->sortStudents();
break;*/
case 4:
out = false;
break;
};
}
}
void university::setStudents(list<students> lstudents) {
this->lstudents = lstudents;
}
void university::registerStudent()
{
lstudents.push_back(students());
}
void university::list()
{
int sum = 0;
cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
cout << left << setw(11) << "Number"
<< left << setw(30) << "Name"
<< left << setw(30) << "Course"
<< left << setw(10) << "Average";
cout << "\n";
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
(*itstudents).list();
++sum;
}
//cout << "Total de pacientes:" << somatorio << endl;
//somatorio = 0;
}
void university::average()
{
int sum = 0;
double average = 0;
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
average += (*itstudents).getaverage();
++sum;
}
cout << "Average:" << average / sum << endl;
}
//void university::sortstudents() {
// sort(lstudents.begin(), lstudents.end(), &students::compare);
//}
students.h
as you can see the commented code is my attempts on sorting the class student my number
#pragma once
#include <iomanip>
#include <algorithm>
#include <list>
#include "university.h"
using namespace std;
class students {
private:
std::string name;
std::string course;
int number;
double average;
public:
//friend bool operator<(estudantes& left,estudantes& right) { return left.matricula < right.matricula; };
students();
void list();
double getaverage();
int getnumber();
//bool compare(estudantes a, estudantes b);
};
students.cpp
#include "students.h"
students::students() {
cout << "Name: ";
getline(cin, name);
cout << "Course: ";
getline(cin, course);
cout << "Number: ";
cin >> this->number;
cout << "Average: ";
cin >> this->average;
}
void students::list() {
cout << left << setw(11) << number;
cout << left << setw(30) << name;
cout << left << setw(30) << course;
cout << left << setw(10) << average << endl;
}
double students::getaverage() {
return average;
}
int students::getnumber() {
return number;
}
//bool estudantes::compare(student a, student b) {
//
// if (a.number < b.number)
// return 1;
// else
// return 0;
//}
Made it selfcontained and fixed. I'll post and then aexplain as surely people will have closed the question too soon:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <string>
class students {
private:
std::string name;
std::string course;
int number;
double average;
public:
// friend bool operator<(students& left,students& right) { return
// left.matricula < right.matricula; };
students();
void list();
double getaverage();
int getnumber();
static bool compare(students const& a, students const& b);
};
students::students()
{
std::cout << "Name: "; getline(std::cin, name);
std::cout << "Course: "; getline(std::cin, course);
std::cout << "Number: "; std::cin >> this->number;
std::cout << "Average: "; std::cin >> this->average;
}
void students::list() {
std::cout << std::left << std::setw(11) << number;
std::cout << std::left << std::setw(30) << name;
std::cout << std::left << std::setw(30) << course;
std::cout << std::left << std::setw(10) << average << std::endl;
}
double students::getaverage() {
return average;
}
int students::getnumber() {
return number;
}
bool students::compare(students const& a, students const& b) {
return a.number > b.number;
}
class university {
private:
std::list<students> lstudents;
std::list<students>::iterator itstudents;
public:
university();
void setStudents(std::list<students> lstudents);
void registerStudent();
void list();
void average();
void sortStudents();
};
university::university() // constructor
{
std::string resp = "s";
int op;
bool out = true;
std::cout << "Enter Students:" << std::endl;
while (resp != "n") {
this->registerStudent();
std::cout << "Continue inserting? (s/n)" << std::endl;
std::cin >> out;
std::cin.ignore();
}
while (out) {
std::cout << "What you Want to do? (1- List Students 2- Sudent Average "
"3- Sort Students by Number 4- Leave)"
<< std::endl;
std::cin >> op;
switch (op) {
case 1: this->list(); break;
case 2:
this->average();
break;
case 3: this->sortStudents(); break;
case 4: out = false; break;
};
}
}
void university::setStudents(std::list<students> lstudents) {
this->lstudents = lstudents;
}
void university::registerStudent()
{
lstudents.push_back(students());
}
void university::list()
{
int sum = 0;
std::cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
std::cout << std::left << std::setw(11) << "Number"
<< std::left << std::setw(30) << "Name"
<< std::left << std::setw(30) << "Course"
<< std::left << std::setw(10) << "Average";
std::cout << "\n";
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
(*itstudents).list();
++sum;
}
//std::cout << "Total de pacientes:" << somatorio << std::endl;
//somatorio = 0;
}
void university::average()
{
int sum = 0;
double average = 0;
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
average += (*itstudents).getaverage();
++sum;
}
std::cout << "Average:" << average / sum << std::endl;
}
void university::sortStudents() {
lstudents.sort(&students::compare);
}
int main() {
university univ = university();
return 0;
}
Explanation
There were a number of issues.
students::compare was a non-static member function, meaning it can only be called on an instance of student. To have a 2-argument sort predicate as required, simply making it static can work
The implementation could be much more idiomatic:
bool students::compare(students const& a, students const& b) {
return a.number > b.number;
}
That avoids the C-ism of using 1 as if it were true, and the useless if/else
You used std::sort but it requires random access iterators. std::list doesn't provide that. For that reason std::list::sort exists:
void university::sortStudents() {
lstudents.sort(&students::compare);
}
Among many other style issues:
don't using namespace std;
don't do side-effects in constructors?
error-check IO
avoid division by zero (e.g. in average()

Two codes; same logic and line of code, one works but other doesn't

I asked this question a couple of hours ago; I want to see if someone can now explain the problem.
One code is about separating items in a grocery; in the end you'll have two(2) bags; a fragileBag and a normalBag.
Other code separates passengers depending on the office they go for pickup; in the end you'll have three(3) types of passengers; ones that go to rio, ones that go to maya, and ones that request elsewhere.
Both codes use the same logic but the passenger code gives an error on a line that works perfectly on the grocery code.
Just to be clear, BOTH CODES RETURN VALUES OF STRING.
ERROR FROM THE PASSENGER CODE:
Error (active) E0304 no instance of overloaded function "std::vector<_Ty,_Alloc>::push_back [with _Ty=trans, _Alloc=std::allocator<trans>]" matches the argument list dataPractice2 C:\Users\javye\source\repos\dataPractice2\dataPractice2\main.cpp 82
and also:
Error C2664 'void std::vector<trans,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'std::string' to 'const _Ty &' dataPractice2 c:\users\javye\source\repos\datapractice2\datapractice2\main.cpp 82
//GROCERY FUNCTION
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //NO PROBLEM HERE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem()); //OR HERE
newMyVector.pop_back();
}
}
}
//PASSENGER FUNCTION
//separate function
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x].getXoLoc()); //PROBLEM HERE
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
}
//GROCERY FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef BAG_H
#define BAG_H
class myBag {
public:
myBag(); //default constructor
myBag(string anItemName); //overload constructor
void addItem(string anItemName); //mutator
string getItem();//accessor
private:
string itemName;
};
#endif
//SOURCE
#include"bag.h"
myBag::myBag() {
addItem("");
}
myBag::myBag(string anItemName) {
addItem(anItemName);
}
void myBag::addItem(string anItemName) {
itemName = anItemName;
}
string myBag::getItem() {
return itemName;
}
//MAIN
#include"bag.h"
void inputItems(vector<myBag>&); //input data function prototype
void displayQuantity(vector<myBag>&); //display data function prototype
void separateItems(vector<myBag>&); //function that separates items; func prototype
void fragBag(vector<myBag>&); //fragile bag function prototype
void norBag(vector<myBag>&); //normal bag function prototype
vector<myBag> myVector; //main vector
vector<myBag> fragileBag, normalBag; //seconday vectors
string item; //global item variable
int main() {
int option;
try {
do {
cout << "\tMENU"
<< endl << "1) Input Items"
<< endl << "2) Display Quantity"
<< endl << "3) Separate (IMPORTANT)"
<< endl << "4) Display Items in Fragile Bag"
<< endl << "5) Display Items in Normal Bag"
<< endl << "6) Exit Program"
<< endl << endl << "Choose: ";
cin >> option;
if (option > 6) {
throw 404;
}
switch (option) {
case 1: //input
system("cls");
inputItems(myVector);
system("pause");
system("cls");
break;
case 2://display
system("cls");
displayQuantity(myVector);
system("pause");
system("cls");
break;
case 3: //separate
system("cls");
separateItems(myVector);
system("pause");
system("cls");
break;
case 4: //fragile
system("cls");
fragBag(myVector);
system("pause");
system("cls");
break;
case 5: //normal
system("cls");
norBag(myVector);
system("pause");
system("cls");
break;
case 6: //exit
exit(0);
}
} while (option != 6);
}
catch(int x){
cout << "ERROR, OPTION DOESN'T EXITS" << endl;
system("pause");
}
}
//input function
void inputItems(vector<myBag>& newMyVector) {
do {
cout << "Enter grocery items || enter letter X to stop: ";
cin >> item;
if (item != "x")
newMyVector.push_back(myBag(item));
} while (item != "x");
}
//display function
void displayQuantity(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "Store bag has " << newMyVector.size() << " items in it. These are: " << endl;
}
cout << newMyVector[x].getItem() << endl;
}
if (newMyVector.empty())
throw 404;
}
catch (int x) {
cout << "ERROR " << x << " ,QUANTITY NOT FOUND" << endl;
}
}
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //PROBLEM WOULD APPEAR HERE, BUT DOESN'T, UNLIKE THE OTHER CODE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem());
newMyVector.pop_back();
}
}
}
//fragile bag function
void fragBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < fragileBag.size(); ++x) {
if (x == 0) {
cout << "The fragile bag has " << fragileBag.size() << " items in it. These are: " << endl;
}
cout << fragileBag[x].getItem() << endl;
}
if (fragileBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x << " ,FRAGILE BAG EMPTY" << endl;
}
}
//normal bag function
void norBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < normalBag.size(); ++x) {
if (x == 0) {
cout << "The normal bag has " << normalBag.size() << " items in it. These are: " << endl;
}
cout << normalBag[x].getItem() << endl;
}
if (normalBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x <<" , NORMAL BAG EMPTY" << endl;
}
}
//PASSENGER FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef TRANSPORT_H
#define TRANSPORT_H
class trans {
public:
trans();
trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum);
void setName(string aName);
void setXoLoc(string anXoLoc);
void setXfLoc(string anXfLoc);
void setTime(string aTime);
void setCellNum(string aCellNum);
string getName();
string getXoLoc();
string getXfLoc();
string getTime();
string getCellNum();
private:
string name;
string xoLoc; //offices
string xfLoc; //destination
string time;
string cellNum;
};
//SOURCE
#include"transport.h"
trans::trans() {
setName("");
setXoLoc("");
setXfLoc("");
setTime("");
setCellNum("");
}
trans::trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum) {
setName(aName);
setXoLoc(anXoLoc);
setXfLoc(anXfLoc);
setTime(aTime);
setCellNum(aCellNum);
}
void trans::setName(string aName) {
name = aName;
}
void trans::setXoLoc(string anXoLoc) {
xoLoc = anXoLoc;
}
void trans::setXfLoc(string anXfLoc) {
xfLoc = anXfLoc;
}
void trans::setTime(string aTime) {
time = aTime;
}
void trans::setCellNum(string aCellNum) {
cellNum = aCellNum;
}
string trans::getName() {
return name;
}
string trans::getXoLoc() {
return xoLoc;
}
string trans::getXfLoc() {
return xfLoc;
}
string trans::getTime() {
return time;
}
string trans::getCellNum() {
return cellNum;
}
#endif
//MAIN
#include"transport.h"
void inputInfo(vector<trans> &);
void displayInput(vector<trans>&);
void separateP(vector<trans>&);
void rio(vector<trans>&);
void maya(vector<trans>&);
void elsewhere(vector<trans>&);
vector<trans> myVector;
vector<trans> rioLoc, mayaLoc, elseLoc;
string newName;
string newXoLoc; //offices
string newXfLoc; //destination
string newTime;
string newCellNum;
//main not ready. Creating each function one by one to them make it look nice
int main() {
int option;
do {
cout << "MENU"
<< endl << "1) input "
<< endl << "2) output "
<< endl << "3) separate"
<< endl << "4) rio passengers"
<< endl << "5) maya passengers"
<< endl << "6) elsewhere passengers";
cin >> option;
switch(option){
case 1:
inputInfo(myVector);
break;
case 2:
displayInput(myVector);
break;
case 3:
separateP(myVector);
break;
case 4:
rio(myVector);
break;
case 5:
maya(myVector);
break;
case 6:
elsewhere(myVector);
break;
case 7:
exit(0);
}
} while (option != 7);
system("pause");
}
void inputInfo(vector<trans> &newMyVector) {
int charSize;
cout << "How many passangers to register: ";
cin >> charSize;
for (int x = 0; x < charSize; ++x) {
cout << "Name of passanger: ";
cin >> newName;
cout << "Office: ";
cin >> newXoLoc;
cout << "Destination: ";
cin >> newXfLoc;
cout << "Time of pickup: ";
cin >> newTime;
cout << "Cellphone: ";
cin >> newCellNum;
if (charSize != 0)
newMyVector.push_back(trans(newName, newXoLoc, newXfLoc, newTime, newCellNum));
}
}
void displayInput(vector<trans>& newMyVector) {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "There are " << newMyVector.size() << " passengers. These are: " << endl;
}
cout << "-----------------------------Passenger #" << x + 1 << endl;
cout << newMyVector[x].getName() << endl;
cout << newMyVector[x].getXoLoc() << endl;
cout << newMyVector[x].getXfLoc() << endl;
cout << newMyVector[x].getTime() << endl;
cout << newMyVector[x].getCellNum() << endl;
}
}
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
}
void rio(vector<trans>& newMyVector) {
for (int x = 0; x < rioLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Rio Piedras is " << rioLoc.size() << " , these are: " << endl;
}
cout << rioLoc[x].getName() << endl;
cout << rioLoc[x].getXoLoc() << endl;
cout << rioLoc[x].getXfLoc() << endl;
cout << rioLoc[x].getTime() << endl;
cout << rioLoc[x].getCellNum() << endl;
}
}
void maya(vector<trans>& newMyVector) {
for (int x = 0; x < mayaLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Mayaguez is " << mayaLoc.size() << " , these are: " << endl;
}
cout << mayaLoc[x].getName() << endl;
cout << mayaLoc[x].getXoLoc() << endl;
cout << mayaLoc[x].getXfLoc() << endl;
cout << mayaLoc[x].getTime() << endl;
cout << mayaLoc[x].getCellNum() << endl;
}
}
void elsewhere(vector<trans>& newMyVector) {
for (int x = 0; x < elseLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in elsewhere is " << elseLoc.size() << " , these are: " << endl;
}
cout << elseLoc[x].getName() << endl;
cout << elseLoc[x].getXoLoc() << endl;
cout << elseLoc[x].getXfLoc() << endl;
cout << elseLoc[x].getTime() << endl;
cout << elseLoc[x].getCellNum() << endl;
}
}
To explain why the second code does not work I first have to explain why the first code appears to work.
myBag::myBag(string anItemName)
can make a bag out of a string. It is a Conversion Constructor. So when
fragileBag.push_back(newMyVector[x].getItem());
is compiled, the compiler quietly inserts a call to the myBag(string) constructor and you get something more like
fragileBag.push_back(myBag(newMyVector[x].getItem()));
which makes no sense logically. It says turn an item in a bag into a bag with one item and insert this new bag into still another bag, fragileBag.
When you look more closely at myBag, you see that it isn't a bag at all. It is a single item and should be renamed to myItem or discarded all together in favour of an all-new all-different myBag that is a wrapper around a vector of string where the strings represent items. This makes
myBag fragileBag;
the real bag.
In other words, the only reason the working code works is it doesn't actually do what the naming implies it does. The code compiles and produces the expected result, but is semantically troubled.
This leads to the confusion with
rioLoc.push_back(newMyVector[x].getXoLoc());
rioLoc is a vector<trans> and can only hold trans. There is no trans::trans(string) to convert a string to a trans so the faulty logic of the grocery code is exposed. As bag and item have been intertwined in grocery, passenger and transport are combined here.
The fix for grocery described above is relatively straight forward. Passenger will need a slightly different solution with both a passenger class to describe the passengers and a transport class to describe the means of transport. transport will have a vector<passenger> member to contain its passengers as well as methods to add and remove the passengers and possibly book-keeping to track the location of the transport, details incompletely specified by the question.
Both codes are pushing string values into a vector that does not hold string values.
Your grocery code uses a vector of myBag objects. The code works because myBag has a non-explicit constructor that takes a single string as input, so the compiler is able to implicitly construct a temporary myBag object to push into the vector.
Your passenger code uses a vector of trans objects. The code fails because trans does not have a constructor that takes a single string as input, so the compiler cannot construct a temporary trans to push into the vector.

Error Variable is Protected

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
void armySkirmish();
void battleOutcome();
string commander = "";
int numberOfHumans = 0;
int numberOfZombies = 0;
class ArmyValues
{
protected:
double attackPower;
double defensePower;
double healthPoints;
public:
void setAttackPower(double a)
{
attackPower = a;
}
void setDefensePower(double d)
{
defensePower = d;
}
void setHealthPoints(double h)
{
healthPoints = h * (defensePower * .1);
}
};
class Zombies: public ArmyValues
{
};
class Humans: public ArmyValues
{
};
int main(int argc, char ** argv)
{
cout << "Input Commander's Name: " << endl;
cin >> commander;
cout << "Enter Number of Human Warriors: " << endl;
cin >> numberOfHumans;
cout << "Enter Number of Zombie Warriors: " << endl;
cin >> numberOfZombies;
armySkirmish();
battleOutcome();
return 0;
}
void armySkirmish()
{
cout << "\nThe Humans tense as the sound of the undead shuffle towards them." << endl;
cout << commander << " shuffles forward with a determined look." << endl;
cout << "The undead form up into ranks and growl a war chant!" << endl;
cout << commander <<" shouts, CHARGE!!!" << endl;
cout << endl;
cout << "Warriors from both sides blitz across the field!" << endl;
cout << endl;
cout << "*The Carnage has begun!*" << endl;
cout << "*Steal, Sparks, and Flesh flies" << endl;
}
void battleOutcome()
{
int zombieLives = numberOfZombies;
int humanLives = numberOfHumans;
int randomNumber = 0;
int humanDeath = 0;
int zombieDeath = 0;
double newHumanLife = 0;
double newZombieLife = 0;
Zombies zombieBattleData;
Humans humanBattleData;
srand(time(NULL));
zombieBattleData.setAttackPower(20.0);
humanBattleData.setAttackPower(35.0);
zombieBattleData.setDefensePower(15.0);
humanBattleData.setDefensePower(20.0);
zombieBattleData.setHealthPoints(150.0);
humanBattleData.setHealthPoints(300.0);
while(zombieLives && humanLives > 0)
{
randomNumber = 1+(rand()%10);
if(randomNumber < 6)
{
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
if(newHumanLife <= 0)
{
humanLives--;
humanDeath++;
}
}else
{
newZombieLife = zombieBattleData.healthPoints - humanBattleData.attackPower;
if(newZombieLife <= 0)
{
zombieLives--;
zombieDeath++;
}
}
}
if(zombieLives <= 0)
{
cout << "Humans have emerged victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}else if(humanLives <= 0)
{
cout << "Zombies have emerges victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}
I know the code wont run properly as of now. What I was doing was a test run to make sure I was receiving no errors. The two errors I'm getting are:
armySimulatorMain.cpp:25:10: error: 'double ArmyValues::healthPoints' is protected
armySimulatorMain.cpp:115:67: error: within this context.
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
This is the case for Attack Power and Health Power however, Defense power is clearing the errors. i don't understand why they are getting flagged. I'm changing the variable through the public function so shouldn't this be allowed?
Also, I'm calling three variables outside of all functions because they are being used by multiple functions. How can I plug those variables somewhere I don't like that they are floating freely above everything?
Thanks guys I can't believe I forgot about getters... Anyway the code runs now much appreciated I'll make sure to remember this time xD
It's not complaining about the line where you set the values; as you say, that uses a public function. But here, you try to read the protected member variables:
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
You only try to read two variables, and those are the ones it complains about.
You'll need a public getter function to read the values.
You need to do something like:
public:
double gethealthPoints()
{
return healthPoints;
}
because attackPower, defensePower, healthPoints are all protected, so if you want to access to any of them you need a getter, otherwise you will always receive an protect error

Console game not working properly

I am making a simple game for learning purposes mostly and I recently ran into this problem. Keep in mind that I'm still a huge beginner. When I go into the game from the menu and write anything in the "Command Line" I instantly starve and dehydrate. I haven't been able to connect to the internet for a couple of days and I've read through the entire program but I can't find anything wrong.
menu.h
#include <iostream>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <dos.h>
#include <windows.h>
#include <WinBase.h>
//-------------//
#include "tutorial.h"
#include "game.h"
void menu() {
std::cout << "-------MENU------- \n";
std::cout << " 1.Play \n";
std::cout << " 2.Tutorial \n";
std::cout << " 3.Exit \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << "Choose Option: ";
int menuOption;
std::cin >> menuOption;
int menuLoop = 0;
while (menuLoop != 1) {
if (menuOption == 1) {
menuLoop = 1;
play();
}
if (menuOption == 2) {
menuLoop = 1;
system("CLS");
tutorial();
}
if (menuOption == 3) {
menuLoop = 1;
std::cout << "Bye!";
Sleep(1000);
}
if (menuOption > 3)
std::cout << "\"" << menuOption << "\"" << " is not a valid option.\n";
}
}
game.h
#include <iostream>
#include <string>
#include <windows.h>
#include <WinBase.h>
//initiating functions
void step();
void run();
void theme();
void starve();
void die();
void dehydrate();
void b();
//globals
std::string name;
std::string commandLine;
int onRoad = 1; // 1 = True, 0 = False
int steps = 0;
double hunger = 0.0;
double thirst = 0.0;
int energy = 5;
void play() {
system("CLS");
std::cout << "Enter your name: \n";
std::cin >> name;
system("CLS");
theme();
Sleep(350);
std::cout << " " << name << "'s Roadtrip\n";
std::cout << "Type \"/help\" for help\n";
std::cout << "---------Command Line---------\n";
std::cin >> commandLine;
while (onRoad != 0){
//------------------Conditions start------------------
// Hunger Conditions
if (hunger = 0){
if (hunger < 0){
std::cout << "You can't eat that, you're not hungry.\n";
b();
}
}
if (hunger > 100){
hunger = 100;
}
if (hunger < 0){
hunger = 0;
}
if (hunger = 100){
starve();
}
else if (hunger > 96){
std::cout << "You're extremely hungry! If you don't eat something quick you're going to die!\n";
b();
}
else if (hunger > 90) {
std::cout << "You're very hungry.\n";
b();
}
else if (hunger > 80) {
std::cout << "You're hungry.\n";
b();
}
// Thirst Conditions
if (thirst = 0){
if (thirst < 0){
std::cout << "You can't drink that, you're not thirsty.\n";
}
}
if (thirst < 0){
thirst = 0;
}
if (thirst > 100) {
thirst = 100;
}
if (thirst = 100){
dehydrate();
}
else if (thirst > 90){
std::cout << "You're extremely thirsty! If you don't drink something quick you're going to die!\n";
b();
}
else if (thirst > 75) {
std::cout << "You're very thirsty.\n";
b();
}
else if (thirst > 50){
std::cout << "You're thirsty.\n";
b();
}
//Energy Conditions
if (energy > 10){
energy = 10;
}
if (energy < 0){
energy = 0;
}
//-------------------Conditions end-------------------
if (commandLine == "/commands"){
std::cout << "-Command- -Action-\n";
std::cout << " /help Displays this menu.\n";
std::cout << " /commands Displays list of commands.\n";
std::cout << " /step Take a step and display total amount of steps.\n";
std::cout << " /run Take 5 steps and consume 5 energy.\n";
std::cout << " Doesn't increase hunger or thirst.\n";
std::cout << " /inventory Displays inventory.\n";
std::cout << " /info Displays stats.\n";
b();
}
if (commandLine == "/step") {
step();
b();
}
if (commandLine == "/info") {
std::cout << name << "'s stats\n";
std::cout << "Hunger: " << hunger << std::endl;
std::cout << "Thirst: " << thirst << std::endl;
std::cout << "Energy: " << energy << std::endl;
b();
}
else {
std::cout << commandLine << " is not a valid command. Type /commands to display commands.\n";
b();
}
}
}
void step(){
steps += 1;
std::cout << steps;
hunger += 5;
thirst += 5;
}
void run() {
steps += 5;
std::cout << steps;
}
void starve(){
std::cout << "You starved to death!\n";
die();
}
void dehydrate(){
std::cout << "You dehydrated!\n";
die();
}
void die(){
std::cout << "Steps taken: " << steps << std::endl;
onRoad = 0;
}
void theme(){
Beep(600, 200);
Beep(500, 200);
Beep(800, 400);
}
// b takes you back to the command line
void b(){
std::cin >> commandLine;
}
main.cpp
#include <iostream>
#include "menu.h"
#include <WinBase.h>
#include <windows.h>
int main(){
menu();
system("PAUSE");
return 0;
}
**EDIT: ** Pic: http://i.imgur.com/yu1V1pq.png (need 10 rep to post picture)
This is really weird. I entered /step and it worked, and then i entered /run and it also worked. I don't understand...
Some of your if statements do assignment instead of comparison
if (hunger = 100){
starve();
}
You probably need to change = to ==
Enable warnings while compiling, if you have not already done so.
Because
// b takes you back to the command line
void b(){
std::cin >> commandLine;
}
b doesn't take you back to the command line just wait for a character to be read and then it returns. If you want to go back, you should follow the way you came from. For example exiting play will return you to the menu loop, obviously with menuLoop = 1 so it will exit the whole program but with modifications this is not a bad looping system.
Edit: I've seen what you do mean in the "command line".
Like others said, you have a load of conditions accidentally spelled as assignments.
Also, indeed, the b() function is eating subsequent commands.
Maybe you should
use std::getline() to read a command one line at a time
or use std::cin.ignore() inside b() to actually consume until the end of the line
PS. Due to the use of globals I have a hard time verifying the game loop logic. I just know that /step after /step gets ignored without effect right now. Separate your input from the loop control and try to remove the global variables.
INFO
Instead of writing std::cout every single time you can just write using namespace std; on the beginning after that you dont need to write std::cout just write cout << "" ;

Giving one class Access to another C++

I am trying to access a member of one class in another class. I am fairly new to C++ so forgive me if this is an easy fix but I cannot find the answer, so I came here.
In this instance I would like to call "init();" from class CGuessNumber and member CheckNumber.
Here is my code.
#include <iostream>
#include <ctime>
#include <cstdlib>
class CGuessNumber
{
public:
int GenerateNumber()
{
return rand() % 100 + 1;
}
void checkNumber(int guess, int answer, int &attempts)
{
if (guess < answer)
{
std::cout << "TOO LOW, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess > answer)
{
std::cout << "TOO HIGH, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess == answer)
{
std::cout << "YOU WON!" << "\n" << "TRYS LEFT: " << attempts << "\n";
}
if (attempts <= 0)
{
std::cout << "YOU LOST!" << "\n" << "TRYS LEFT: " << attempts << "\n";
CGAME::init(answer, attempts);
}
}
}Number;
class CGAME
{
public:
void init(int &answer, int &attempts)
{
answer = Number.GenerateNumber();
attempts = 5;
};
int newGame()
{
srand (time(NULL));
int intAnswer, playerGuess, trys;
init(intAnswer, trys);
while(intAnswer != playerGuess and trys > 0)
{
std::cin >> playerGuess;
Number.checkNumber(playerGuess, intAnswer, trys);
}
};
}ONewGame;
int main()
{
CGAME ONewGame
ONewGame.newGame();
return 0;
}
I think, this is what you're looking for
Basically you can pass a pointer which points to one object into a constructor of the other. In this case we just pass a pointer to CGuessNumber into the CGAME constructor, we also store this pointer in a private field so we can use it. Then you can use this pointer to call methods.
working example (pointer->method syntax)
working example (reference.method syntax)
#include <iostream>
#include <ctime>
#include <cstdlib>
class CGuessNumber
{
public:
int GenerateNumber()
{
return rand() % 100 + 1;
}
void checkNumber(int guess, int answer, int &attempts)
{
if (guess < answer)
{
std::cout << "TOO LOW, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess > answer)
{
std::cout << "TOO HIGH, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess == answer)
{
std::cout << "YOU WON!" << "\n" << "TRYS LEFT: " << attempts << "\n";
}
if (attempts <= 0)
{
std::cout << "YOU LOST!" << "\n" << "TRYS LEFT: " << attempts << "\n";
}
}
};
class CGAME
{
public:
CGAME(CGuessNumber* pNumber)
{
m_number = pNumber;
}
void init(int &answer, int &attempts)
{
answer = m_number->GenerateNumber();
attempts = 5;
};
void newGame()
{
srand (time(NULL));
int intAnswer, playerGuess, trys;
init(intAnswer, trys);
while(intAnswer != playerGuess and trys > 0)
{
std::cin >> playerGuess;
m_number->checkNumber(playerGuess, intAnswer, trys);
}
};
private:
CGuessNumber* m_number;
};
int main()
{
CGuessNumber* pGnum = new CGuessNumber();
CGAME* ONewGame = new CGAME(pGnum);
ONewGame->newGame();
return 0;
}
Let me just address the syntax errors.
In the checkNumber() function:
...
CGAME::init(answer, attempts);
...
There are 2 problems with this:
CGAME is not declared yet, so the compiler doesn't know it exists, or what it is. To avoid this, usually all the classes are declared at the top (or in a header file) and all there functions are defined later.
You can't call a member function of a class without an object, unless it's a static function. This function can be static as it doesn't use member variables (there are design issues, but lets ignore them for now).
Also in main() you missed a ';', but I think you already know that :-)
So, applying these changes:
#include <iostream>
#include <ctime>
#include <cstdlib>
// only declaring the classes here
class CGAME
{
public:
static void init(int &answer, int &attempts);
int newGame();
}ONewGame;
class CGuessNumber
{
public:
int GenerateNumber();
void checkNumber(int guess, int answer, int &attempts);
}Number;
// defining all the class member functions now
int CGAME::newGame()
{
srand (time(NULL));
int intAnswer, playerGuess, trys;
init(intAnswer, trys);
while(intAnswer != playerGuess and trys > 0)
{
std::cin >> playerGuess;
Number.checkNumber(playerGuess, intAnswer, trys);
}
}
int CGuessNumber::GenerateNumber()
{
return rand() % 100 + 1;
}
void CGuessNumber::checkNumber(int guess, int answer, int &attempts)
{
if (guess < answer)
{
std::cout << "TOO LOW, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess > answer)
{
std::cout << "TOO HIGH, TRY AGAIN" << "\n" << "TRYS LEFT: " << attempts << "\n";
attempts--;
}else if(guess == answer)
{
std::cout << "YOU WON!" << "\n" << "TRYS LEFT: " << attempts << "\n";
}
if (attempts <= 0)
{
std::cout << "YOU LOST!" << "\n" << "TRYS LEFT: " << attempts << "\n";
CGAME::init(answer, attempts);
}
}
void CGAME::init(int &answer, int &attempts)
{
answer = Number.GenerateNumber();
attempts = 5;
}
int main()
{
CGAME ONewGame;
ONewGame.newGame();
return 0;
}