main.cpp :
#include <iostream>
#include <string>
#include "Players.h"
using namespace std;
int main ()
{
cout << "**** Welcome to Leviathan's first TicTacToe Game! ****\n\n";
Players getNamesobject;
Players printNamesobject;
getNamesobject.getPlayersNames();
printNamesobject.printPlayersNames();
}
Players.h:
#ifndef PLAYERS_H
#define PLAYERS_H
class Players
{
public:
void getPlayersNames();
void printPlayersNames();
private:
std::string _player1Name;
std::string _player2Name;
};
#endif // PLAYERS_H
Players.cpp :
#include <iostream>
#include <string>
#include "Players.h"
using namespace std;
void Players::getPlayersNames()
{
string p1,p2;
cout << "Enter player 1 name : ";
cin >> p1;
cout << "\nEnter player 2 name : ";
cin >> p2;
_player1Name = p1;
_player2Name = p2;
}
void Players::printPlayersNames()
{
cout << "Alright " << _player1Name << " and " << _player2Name <<", the game has begun!\n\n";
}
When i run this, and enter two names, the _player1Name and _player2Name variables don't get changed. I've tried setting them a string manually and they get printed normally. Can anyone explain what's wrong here? It seems like getPlayerNames function can't change the private variables?
It's because you have two different objects!
One that you set the member variables in (through the getPlayersNames function), and another unrelated object you use to print a different set of variables.
You should have a single object, and call getPlayersNames and printPlayersNames on that single object. Like
Players playersObject;
playersObject.getPlayersNames();
playersObject.printPlayersNames();
Each instance of the Players object you create will have its own set of member variables that are tied to that single object, member variables are not shared between objects (unless you make them static).
Related
I am making a small console game and I have a player class with private integers for the stats and a private string for the name. What I want to do is to ask the user for their name, and store that into the private name variable in the player class. I got an error stating:
error: no match for 'operator>>'
(operand types are 'std::istream {aka std::basic_istream<char>}' and 'void')
Here is my code:
main.cpp
#include "Player.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
Player the_player;
string name;
cout << "You wake up in a cold sweat. Do you not remember anything \n";
cout << "Do you remember your name? \n";
cin >> the_player.setName(name);
cout << "Your name is: " << the_player.getName() << "?\n";
return 0;
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <string>
using namespace std;
class Player {
public:
Player();
void setName(string SetAlias);
string getName();
private:
string name;
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
#include <string>
#include <iostream>
Player::Player() {
}
void Player::setName(string setAlias) {
name = setAlias;
}
string Player::getName() {
return name;
}
The return type for the setName function is void, not a string. So you have to store first the variable in a string, and then pass it to the function.
#include "Player.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
Player the_player;
cout << "You wake up in a cold sweat. Do you not remember anything \n";
cout << "Do you remember your name? \n";
string name;
cin >> name;
the_player.setName(name);
cout << "Your name is: " << the_player.getName() << "?\n";
return 0;
}
If you surely want use function, should return object reference.
string& Player::getNamePtr() {
return name;
}
cin >> the_player.getNamePtr();
Firstly, try to get the value in the name variable from the user and then call the setName method of the class Player:
cin>>name;
the_player.setName(name);
I'm using a vector v to store a class object called t_display. I've checked with the debugger and I can see the display object is instantiated correctly. However, when I pass it into the vector with v.push_back() or v.insert(), it stores every value as -842150451. I can see this in the print statements and in the debugger and I cant figure out why it's storing the object this way. Additionally, its storing the integer values this way every time i execute the program, which leads me to believe its not a memory issue although i cant be sure. I've checked all over stack overflow and cppreference. Any advice would be appreciated.
here is the class where I create the object and pass into the vector. I just want the vector to contain the newly made object t_display at the first element.
Animation.cpp
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"
#include "Animation.h"
void Animation::InsertFrame() {
int numDisplays;
vector <Display>v;
int p_x;
int p_y=0;
int p_duration=0;
string p_name;
string frameName;
cout << "Insert a Frame in the Animation\nPlease enter the Frame filename" << endl;
cin >> frameName;
cout << "Entering the Frame Displays (the sets of dimensions and durations) " << endl;
cout << "Please enter the number of Displays :" << endl;
cin >> numDisplays;
vector <Display>::iterator it;
it = v.begin();
while (numDisplays > 0) {
cout << "Please enter pixel x for Display #0 pixel_x:";
cin >> p_x;
cout << "\nPlease enter pixel y for Display #0 pixel_y:" << endl;
cin >> p_y;
cout << "\nPlease enter the duration sec for this Display :" << endl;
cin >> p_duration;
cout << "\nPlease enter the name for this Display : " << endl;
cin >> p_name;
Display t_display = Display(p_x, p_y, p_duration, (char *)p_name.c_str());
//it = v.insert(it, t_display);
v.push_back(t_display);
numDisplays--;
}
Display.h
// Display.h
#pragma once
class Display
{
int pixel_x;
int pixel_y;
int duration;
char* name;
public:
Display(int x, int y, int duration, char* name);
Display(const Display&);
~Display();
friend ostream& operator<<(ostream&, Display&);
};
## Display.cpp ##
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"
int q = 0;
Display::Display(int x, int y, int d, char* n):pixel_x(x), pixel_y(y), duration(d), name(n) {}
Display::Display(const Display&) {
}
Display::~Display() {
}
It turns out that I didn't write a copy constructor.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I have a class Player and a class Team.
I want to create a vector of Players in constructor of class Team. I have written a method called fillVector witch creates all the players. I have added method fillVector into class Team witch is shown bellow. I do not think class Player is necessary.
When I compile my programm with codeblocks there is the following error:
Team.cpp|9|undefined reference to `Team::fillTeamVector(std::vector >&)'|
|error: ld returned 1 exit status|
This is the Team.cpp code :
#include "Team.h"
#include <vector>
#include <iostream>
#include "Player.h"
Team::Team()
{
vector<Player> team;
fillTeamVector(team);
}
void fillTeamVector(vector<Player>& team){
cout << "How many players are in the team? " <<endl;
string name;
int teamSize,x,y,num,target_line;
cin >> teamSize;
for (int i=0 ; i<=teamSize ; i++){
cout << "Give player's name" << endl;
cin >> name;
cout << "Give player's number" << endl;
cin >> num;
cout << "Give player's x position" << endl;
cin >> x;
cout << "Give player's y position" << endl;
cin >> y;
cout << "Give player's target line" << endl;
cin >> target_line;
Player newPlayer(name,num,x,y,target_line);
team.push_back(newPlayer);
}
}
This is the Team.h code :
#ifndef TEAM_H
#define TEAM_H
#include <iostream>
#include <vector>
#include "Player.h"
using namespace std;
class Team
{
public:
Team();
void fillTeamVector(vector<Player>&);
};
#endif // TEAM_H
This is the main.cpp code :
#include <iostream>
#include <stdio.h>
#include "Player.h"
#include "Team.h"
using namespace std;
int main()
{
Team team;
return 0;
}
You have defined "fillTeamVector" as a free function in team.cpp, while it's a member function in the .h.
So fillTeamVector method of Team does not exist, but is called, hence the error.
In team.cpp, replace this :
void fillTeamVector(vector& team)
by this :
void Team::fillTeamVector(vector& team)
You've declared the function:
void fillTeamVector(vector<Player>& team){ // ...
But you forgot the "class-scope", that because that function is a member-function so you have to add:
void Team::fillTeamVector(vector<Player>& team){ // ...
Exactly what you've done for the constructor (Team::Team()).
You wrote a function called fillTeamVector.
This is not the same thing as a class method called Team::fillTeamVector, which is called by the constructor.
Another question for those far wiser than I:
I'm trying to create 3 instances of a Player Class like so:
Player *player1 = new Player("Aaron",0.3333333);
Player *player2 = new Player("Bob",0.5);
Player *player3 = new Player("Charlie",1);
You can see their constructor below. It's really simple:
Player::Player(string n, double hr)
{
name = n;
hitrate = hr;
}
(just assume name and hitrate are defined properly)
Now my problem is this, when I try to check each individual player for their name, it seems they have all become aliases of sorts for player3
//Directly after the player instantiations:
cout << player1->getName() << "\n";
cout << player2->getName() << "\n";
cout << player3->getName() << "\n";
//In the Player.cpp file:
string Player::getName(){
return name;
}
Outputs:
Charlie
Charlie
Charlie
Alright, so I'd really like to know the best solution to get around this problem but more importantly I just want to understand why it's behaving this way. It seems like such a simple thing (being spoiled by java as I am).
Also it's important to note: this is for a school assignment and I am told that I MUST use dynamically allocated objects.
Thanks so much, and do let me know if anything needs clarifying.
Edit: By demand, here are the full files:
PlayerTest.cpp
#include <iostream>
#include <player.h>
using namespace std;
int main(){
Player *player1 = new Player("Aaron",0.3333333);
Player *player2 = new Player("Bob",0.5);
Player *player3 = new Player("Charlie",1);
cout << player1->getName() << "\n";
cout << player2->getName() << "\n";
cout << player3->getName() << "\n";
return 0;
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <string>
using namespace std;
class Player
{
public:
Player(string, double);
string getName();
};
//Player.cpp
#include "Player.h"
string name;
double hitrate;
Player::Player(string n, double hr)
{
name = n;
hr = hitrate;
}
string Player::getName(){
return name;
}
#endif // PLAYER_H
The name and hitrate variables need to be inside the Player class declaration so that each object gets its own separate copies.
class Player
{
public:
Player(string, double);
string getName();
private:
string name;
double hitrate;
};
I'm writing a program that uses OOP to store student records. At the moment I only have two classes, one for each individual course module called 'Courses', and one ( well two if you count the abstract base class) for the type of degree programme called 'Physics' derived from the 'Records' base class.
I'm using two maps in the program. One to store the individual courses for each individual record and sort them by course code, and one to store all the records and sort them by ID numbers.
I planned on having the user input all student information, including codes, storing this in a vector (named 'prec' in the code), then pushing the vector elements into the map used to store all the records. The code is far from finished, I was just attempting to run it to see if I was on the right track.
The code builds without any errors, but when I attempt to run it, it comes up with the error message: " Debug assertion failed: expression vector subscript out of range". I feel this may have something to do with the way I am using individual vector elements to call my functions to store courses in the maps but I cant quite get it, any help would be much appreciated!
Here are my files:
header file:
#ifndef MY_CLASS_H // Pre-processor directives to prevent multiple definition
#define MY_CLASS_h
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <fstream>
using std::string;
using std::ostream;
using std::map;
using std::cout;
using std::endl;
using std::cin;
namespace student_record // Defines the namespace student_record in which the classes are defined
{
class Course { /* Create class Course for individual courses, is this better than incorporating
all the data separately into the Record class below? Class contains course name, mark achieved and mark weight and course ID */
protected:
string course_name;
double course_mark;
int course_Id;
public:
Course() {course_name= "Null"; // Default constructor for null course
course_mark=0;
}
Course(string course_namein, double course_markin, int course_Idin) {course_name=course_namein; // Parametrized constructor to create course with set name, mark, weight and course ID
course_mark=course_markin;
course_Id=course_Idin;}
~Course() {course_name.erase(0,course_name.size());} // Destructor to delete the course name
// Access functions to get name, mark and weight //
double getmark() const {return course_mark;}
string getname() const {return course_name;}
int getid() const {return course_Id;}
friend ostream & operator << (ostream &os, const Course &c); // Friend function to overload the insertion operator for courses
};
class Record
{ // Create class Record as abstract base class for all inherited degree classes
protected:
string student_name;
int studentid;
int years;
public:
Record() {student_name="Casper";
studentid=0;
years=0;} // Default constructor for class Record, produces empty record
Record(string name, int number, int time) {student_name=name;
studentid=number;
years=time;} // Parametrized constructor for class Record
~Record() {student_name.erase(0, student_name.size());} // Destructor to delete the student name
virtual int getid()const=0;
virtual int getyears()const=0;
virtual void show_record()const=0;
virtual void print_record(string *filename)const=0;
virtual void degree_class()const=0;
virtual void insert_class()=0;
/* Virtual functions defined to be used in the derived classes (subjects ie, Physics, stamp collecting, etc...)
Thus the base class Record is abstract*/
};
class Physics: public Record
{
private:
string degree_name;
typedef map <int, Course> course_map;
course_map modules;
void searchdatabase (course_map &courses, int coursecode)const; // Uses iterator to search map for corresponding course to inputted key ( remember to move to function definitions)
string get_name (const int i, course_map &temp) const{ return temp[i].getname();}
double get_mark(const int i, course_map &temp)const{ return temp[i].getmark();} // Functions to return the mark, weight and name of a given course corresponding to inputed course code
int getid()const{return studentid;}
int getyears()const{return years;}
void show_record()const;
void print_record( string *filename) const;
void degree_class()const;
void insert_class();
// Function to insert record into map
public:
Physics():Record(){degree_name= "Physics ";}
Physics(string name,int Id, int time):Record( name, Id, time){degree_name= "Physics";}
~Physics() {degree_name.erase(0, degree_name.size());}
};
}
#endif
function definitions:
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <fstream>
#include <vector>
#include "Database_header.h"
using namespace std;
using namespace student_record;
ostream & student_record::operator<< (ostream &os, const Course &c)
{
os<< "Course code" << c.course_Id << " \n Course name: " <<c.course_name << " \n Mark " << c.course_mark <<endl;
return os;
}
// Function to insert classes //
void Physics::insert_class()
{
int courseid;
string coursename;
double mark;
cout << " Enter course code " << endl;
cin >> courseid;
cout << " \n Enter course name " << endl;
cin >> coursename;
cout << " \n Enter mark achieved " << endl;
cin >> mark;
Course temp (coursename, mark, courseid);
modules.insert(pair<int, Course>(courseid, temp));
}
void Physics::searchdatabase(course_map &courses, int coursecode) const // Function to search for specific course mark based on course code, need to modify this!!!!
//takes in a map as its argument, although i suppose can use student.modules?
{
course_map::iterator coursesIter;
coursesIter=courses.find(coursecode);
if(coursesIter != courses.end())
{
cout << " Course Code " <<
coursecode << " corresponds to " <<
coursesIter ->second << endl;
}
else { cout << " Sorry, course not found " << endl; }
}
void Physics::print_record( string *filename) const // Function for printing record to the file
{
ofstream myoutputfile;
myoutputfile.open(*filename,ios::app);
if(!myoutputfile.good())
{
// Print error message and exit
cerr<<"Error: file could not be opened"<<endl;
}
if(myoutputfile.good())
{
myoutputfile << "Student name: " << student_name << endl
<< "\n Student ID: " << studentid << endl
<< "\n Year: " << years << endl;
course_map::iterator modulesiter; // Iterator to print out courses using overloaded << function (I think?)
for(modulesiter==modules.begin();modulesiter!=modules.end();modulesiter++)
{
myoutputfile<<modulesiter->second << endl;
}
}
}
void Physics::show_record() const // Function for showing specific student record on screen ( with iterator for map of courses)
{
cout << "Student name: " << student_name;
cout << "\n Student ID: " << studentid;
cout << "\n Years on course: " << years;
cout << "\n Courses and grades: ";
course_map::iterator modulesiter; // Iterator to print out courses using overloaded << function (I think?)
for(modulesiter==modules.begin();modulesiter!=modules.end();modulesiter++)
{
cout<<modulesiter->second << endl;
}
}
void Physics::degree_class()const
{
double temp;
vector<double> dynarr; // Create a vector array to store the grades extracted from the course map for each student
course_map::iterator modulesiter;
for(modulesiter==modules.begin();modulesiter!=modules.end();modulesiter++) // Iterate through map and push values into each vector
{
Course ghost;
ghost=modulesiter->second;
dynarr.push_back(ghost.getmark());
}
double sum(0);
for(int i(0);i<=dynarr.size();i++)
{
sum+=dynarr[i];
}
temp=sum/dynarr.size();
if( temp>=40 && temp <=49.9)
{
cout << "The student has achieved a 3rd class degree with an average of: \n "
<< temp;
}
else if( temp>=50 && temp <=59.9)
{
cout << "The student has achieved a 2:2 degree with an average of: \n "
<< temp;
}
else if( temp>=60 && temp <=69.9)
{
cout << "The student has achieved a 2:1 degree with an average of: \n "
<< temp;
}
else if( temp>=70)
{
cout << "The student has achieved a 1st class degree with an average of: \n "
<< temp;
}
else { cout << "The student has failed the degree " << endl;}
}
and main cpp file:
#include <iostream>
#include <utility>
#include <map>
#include <iomanip>
#include <vector>
#include "Database_header.h"
#include <fstream>
using namespace std;
using namespace student_record;
void main()
{
// Create map to store students with ID keys //
string full_name;
int id;
int time;
string degree_name;
vector<Record*> prec;
// Vector of base class pointers to store all the different records first. No need to specify length as it is a vector! (Advantage over dynamic array?)
char student_test('y'); // Condition for adding students to the record //
int q(0);
while (student_test=='y' || student_test=='Y')
{
// Counter for while loop
cout<< " \n Please enter the student name " << endl;
getline(cin, full_name);
// Enter student name, check it is a string? //
cout<< "\n Please enter student ID " << endl;
cin >> id;
// Check if not integer or number, if not need error message //
cout << "\n Please enter the number of years on the course " << endl;
cin >> time;
// Check if not integer or number, if not need error message //
cout<< "\n Please enter degree type " << endl;
cin>>degree_name;
if(degree_name=="Physics" || degree_name=="physics") // create object of appropriate derived class ( Physics, Chem, Maths, Bio)
{
prec.push_back(new Physics(full_name, id, time));
}
char class_test('y'); // test condition for class insertion loop
while(class_test=='y') // Add courses+marks into course map
{
cout << " \n Add classes to student record " << endl;
prec[q]->insert_class();
cout << " \n Add another class? Y/N" << endl;
cin>>class_test;
}
cout << "Enter another student? Y/N " << endl;
cin >> student_test;
if(student_test=='N' && student_test=='n')
{
cout << "\n Thank you for using the student database, Goodbye !" << endl;
}
q++; // increment counter, to keep track of of vectors of base class pointers, and also be able to output number of students
}
// Next insert all records into map //
typedef map<int, Record*> studentlist;
studentlist studentmap;
for(int i(0); i<=prec.size(); i++)
{
studentmap.insert(pair<int, Record*> (prec[i]->getid(), prec[i]));
}
}
Thanks so much!
for(int i(0); i<=prec.size(); i++)
{
studentmap.insert(pair<int, Record*> (prec[i]->getid(), prec[i]));
}
Should be i < prec.size() instead of <=