I am having a problem creating a simple class object. I created a small program to simulate the problem. I have a class "Person" with data members string name, string eye_color, and int pets. When I call Person new_person("Bob", "Blue", 3), my debugger shows this as the new_person's value:
{name=""eye_color=""pets=-858993460}
I'm looking at previous projects where I had no problems with this and am not spotting anything...What am I missing?
person.h
#include <iostream>
#include <string>
class Person
{
public:
Person(std::string name, std::string eye_color, int pets);
~Person();
std::string name;
std::string eye_color;
int pets;
};
person.cpp
#include "person.h"
Person::Person(std::string name, std::string eye_color, int pets)
{
this->name;
this->eye_color;
this->pets;
}
Person::~Person(){}
city.h
#include "person.h"
class City
{
public:
City();
~City();
void addPerson();
};
city.cpp
#include "city.h"
City::City(){}
City::~City(){}
void City::addPerson(){
Person new_person("Bob", "Blue", 3);
}
main.cpp
#include "city.h"
int main(){
City myCity;
myCity.addPerson();
}
It doesn't look like you are actually assigning the values in the Person class so that is why you are getting random values for those data members.
It should be:
Person::Person(std::string name, std::string eye_color, int pets)
{
this->name = name;
this->eye_color = eye_color;
this->pets = pets;
}
Related
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
My code is raising this error:
supportCrew.cpp:(.text+0x15): undefined reference to `sportsPsychologist::sportsPsychologist()'
supportCrew.cpp:(.text+0x25): undefined reference to `Physiotherapist::Physiotherapist()'
supportCrew.cpp:(.text+0x35): undefined reference to `trainer::trainer()'
supportCrew.cpp:(.text+0x47): undefined reference to `trainer::trainer()'
The two relevent classes/cpp files are supportCrew and Person
Person.cpp
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <chrono>
#include <random>
#include <algorithm>
Person::Person(std::string pName, int pAge, int pExperience) {
name = pName;
age = pAge;
experience = pExperience; //years of experience
};
Athlete::Athlete(std::string name, int age, int experience, std::string gender, double height, double weight)
{
gender = gender;
height = height;
weight = weight;
};
Physiotherapist::Physiotherapist(std::string name, int age, int experience, int recovery, int readiness) {
readinessScore = readiness;
recoveryScore = recovery;
};
sportsPsychologist::sportsPsychologist(std::string name, int age, int experience, int pressure, int injury, int successFail) {
pressurescore = pressure;
injuryscore = injury;
successfailscore = successFail;
};
trainer::trainer(std::string name, int age, int experience,std::string specialization, int performance, int consistency) {
specialization = specialization;
performanceScore = performance;
consistencyScore = consistency;
};
Person.h
#ifndef PERSON
#define PERSON
class Person {
std::string name;
int experience; //in years
int age;
public:
Person(std::string pName, int pAge, int pExperience);
Person();
virtual ~Person(){};
std::string getName() {return randomName();};
int getAge(){return randomAge();};
int getExperience(){return randomExperience();};
void printData(std::string, int, int);
std::string randomName();
int randomAge();
int randomExperience();
};
class Athlete: public Person{
private:
std::string gender;
double height;
double weight;
public:
Athlete(std::string pName, int pAge, int pExperience, std::string gender, double height, double weight);
Athlete();
virtual ~Athlete(){};
std::string &getGender(){return gender;};
std:: string randomGender();
double randomHeight();
double randomWeight();
};
class Physiotherapist: public Person{
private:
int recoveryScore;
int readinessScore;
public:
Physiotherapist(std::string pName, int pAge, int pExperience, int recoveryScore, int readinessScore);
Physiotherapist();
int &getscoreRecovery(){return recoveryScore;};
int &getscoreReadiness(){return readinessScore;};
};
class sportsPsychologist: public Person {
private:
int pressurescore;
int injuryscore;
int successfailscore;
public:
sportsPsychologist(std::string pName, int pAge, int pExperience, int pressureScore, int injuryScore, int successfailScore);
sportsPsychologist();
int &getscorePressure(){return pressurescore;};
int &getscoreInjury(){return injuryscore;};
int &getscoreSuccues_Fail(){return successfailscore;};
};
class teamManager: public Person {
public:
teamManager(std::string pName, int pAge, int pExperience);
teamManager();
};
class trainer: public Person {
private:
std::string specialization;
int performanceScore;
int consistencyScore;
public:
trainer(std::string pName, int pAge, int pExperience, std::string specialization, int performanceScore, int cocsistencyScore);
trainer();
std::string &getSpecialization(){return specialization;};
int &getscorePeformance(){return performanceScore;};
int &getscoreConsistency(){return consistencyScore;};
};
#endif
supportCrew.h
#ifndef SUPPORTCREW
#define SUPPORTCREW
#include "Person.h"
class supportCrew {
private:
sportsPsychologist Psychologist;
Physiotherapist physio;
trainer trainer1;
trainer trainer2;
public:
supportCrew(sportsPsychologist,Physiotherapist,trainer,trainer);
supportCrew();
};
#endif
supportCrew.cpp
#include <iostream>
#include <sstream>
#include <fstream>
#include "compDay.h"
#include "Competion.h"
#include "Events.h"
#include "Location.h"
#include "Octathlon.h"
#include "Person.h"
#include "supportCrew.h"
#include "theTeam.h"
#include "weatherSystem.h"
supportCrew::supportCrew() {
}
It seem the skill you are missing is how to call base class constructors. So
Physiotherapist::Physiotherapist(std::string name, int age, int experience, int recovery, int readiness) {
readinessScore = readiness;
recoveryScore = recovery;
};
should really be
Physiotherapist::Physiotherapist(std::string name, int age, int experience, int recovery, int readiness)
: Person(name, age, experience) {
readinessScore = readiness;
recoveryScore = recovery;
}
If you do that then the Person::Person() constructor isn't required because you are explicitly calling the Person::Person(std::string pName, int pAge, int pExperience); constructor.
Of course you should be using initialization lists everywhere. So the above code is even better written like this
Physiotherapist::Physiotherapist(std::string name, int age, int experience, int recovery, int readiness)
: Person(name, age, experience)
, readinessScore(readiness)
, recoveryScore(recovery) {
}
If you don't call the base class construcor from an initialization list, then the default base class constructor will be called implicitly. I guess this is why you've decalred all these default constructors. But if you code it like I show you above then you (probably) don't need all these default constructors.
I am coding a little RPG(Role Playing Game)
Here is the situation: I created an object Personnage.
In my classes, I created a method atttaquer. But I would like that after calling my method attaquer it writes something like this: Goliath attaque David . But to that, I need to grab the name of the Object. Because the player may want to edit the name of Object (The personage name) before playing.
There is my code:
Personnage.h
#ifndef Personnage_h
#define Personnage_h
#include <string>
#include "Arme.h"
class Personnage{
//methods
public:
Personnage();
Personnage(std::string nomArme, int degatsArme);
Personnage(int vie, int mana);
// ~Personnage();
void recevoirDegats(int nbDegats);
void attaquer(Personnage &cible);
private:
// Attributs
int m_vie;
int m_magie;
std::string m_nom;
};
#endif
My Personnage.cpp code:
#include "Personnage.h"
#include <string>
#include <iostream>
void Personnage::recevoirDegats(int nbDegats){
m_vie -= nbDegats;
if (m_vie < 0) {
m_vie = 0;
}
}
void Personnage::attaquer(Personnage &cible){
cible.recevoirDegats(m_arme.getDegats());
// if David attacks Goliath I want to write std::cout << David << "attaque "<< Goliath << endl; but I do not know how to grab the name of the object after it's creation
}
There is my main.cpp
#include <iostream>
#include <string>
#include "Personnage.h"
//#include "Personnage.cpp"
#include <ctime>
using namespace std;
int main()
{
Personnage David, Goliath, Atangana("Ak47", 35);
Goliath.attaquer(David);
return 0;
}
If you want to give your objects names, it cannot be the variable names. They are only meant for the compiler and they are fixed. So you need to create a class that can have a name:
class NamedObject
{
private:
std::string m_name;
public:
const std::string& getName() const
{
return m_name;
}
void setName(const std::string& name)
{
m_name = name;
}
}
And if you want your classes to have a name, the easiest way would be to derive from it:
class Personnage : NamedObject {
Then you can say:
Personnage player1, player2;
player1.setName("David");
player2.setName("Goliath");
Alternatively, you can get those string from user input.
And if you need to address one by name:
std::cout << player1.getName() << " please make your move." << std::endl;
I have a class named Student with its Name and Address classes.
#ifndef ADDRESS_H
#define ADDRESS_H
//This is address class
#include <string>
class Address{
public:
Address(std::string street, std::string city, std::string state, std::string zip) :
street(street), city(city),state(state),zip(zip)
{}
std::string street,city,state,zip;
std::string aString;
aString=street+city+state+zip;
//private:
};
#endif
and the Name class is
#ifndef NAME_H
#define NAME_H
#include <iostream>
#include <string>
class Name {
friend std::ostream &operator <<(std::ostream &os, const Name &name) {
if(name.middle!="")
os << name.last << ", "<<name.middle<<" ," << name.first;
else
os<< name.last <<", "<<name.first;
return os;
}
public:
Name(std::string last, std::string middle, std::string first) : last(last), first(first),middle(middle) {}
private:
std::string last, first, middle;
};
#endif
And the Student class is like:
#ifndef PERSON_H
#define PERSON_H
#include <iostream>
#include <string>
#include "name.h"
#include "Address.h"
class Person {
friend std::ostream &operator <<(std::ostream &os, const Person &person);
public:
Person(const Name &name, int age, const Address &address);
Address address;
std::string adr=address.aString;
//private:
Name name;
int age;
};
#endif
Finally, to call them.
#include <iostream>
#include "student.h"
#include <string>
using namespace std;
Person::Person(const Name &name, int age, const Address &address) : name(name), age(age),address(address) {}
ostream &operator <<(ostream &os, const Person &person) {
os << person.name << " " << person.age<<person.adr;
return os;
}
#include <iostream>
#include "student.h"
using namespace std;
int main() {
Person p(Name("Doe","","Jane"), 21, Address("Park Ave","New York","NY","10002"));
Person p2(Name("Bane","IHateM","Jane"), 21, Address("Bay parkway","Brooklyn","NY","11223"));
cout << p<<endl;
cout<< p2<<endl;
return 0;
}
However, there are some errors during compilation.
(1) The following line is wrong based on complier, how to fix it please?
std::string adr=address.aString;
(2) In my address class, the compiler said that "string does not name a type Error", but following this Why am I getting string does not name a type Error? can't fix the problem, why is that?
Simple Solution
The simplest solution is to move your aString=street+city+state+zip; inside the Address constructor.
Do the same for your adr = ... statement (you'll still need a 'declaration' for std::string adr; within your class header).
To understand why what you wrote won't work, consider this:
When you write (within a class declaration, like in your header)
class myClass
{
int a = 5;
};
you assign a default value to the int a that you have declared - this is both declaration and (default) assignment.
When you write
class Address{
public:
Address(std::string street, std::string city, std::string state, std::string zip) :
street(street), city(city),state(state),zip(zip)
{}
std::string street,city,state,zip;
std::string aString;
aString=street+city+state+zip;
};
you're trying to give a default assignment to aString, but this is invalid code.
You could do this using
std::string aString = ...;
but not
std::string aString;
aString = ...;
because the last line is a 'statement' - something to be executed.
I'm trying to simply use a vector within one of my classes. When trying to access the vector it tells me that it's undefined (but I've defined it in my header).
I have two classes, Person and Dog. A person can own one or more dogs so I want to add each dog a person owns into an array. This should be real simple so this problem is really starting to get to me. Here's some code:
The class Person.cpp:
#include "Person.h"
#include "stdafx.h"
#include <iostream>
using namespace std;
Person::Person(string name, string address, int age)
:name(name),
address(address),
age(age)
{}
int Person::getAge(){
return age;
}
std::string Person::getDogInfo(int index){
}
void Person::addDog(string dogName, string breed){
dogCollection.push_back(Dog(dogName, breed));
}
std::vector<Dog> getDogs(){
return dogCollection; //dogCollection undefined error here
}
And here's Person.h:
#ifndef Person_H
#define Person_H
#include <vector>
#include "Dog.h"
using namespace std;
class Person{
public:
Person(string name, string address, int age);
string getName(){return name};
string getAddress(){return address};
void addDog(string dogName, string breed);
string getDogInfo(int index);
std::vector<Dog> getDogs();
int getAge();
private:
string name;
string address;
int age;
std::vector<Dog> dogCollection;
};
#endif
If you want to have a look at my dog classes I'll paste them as well:
Dog.cpp:
#include "stdafx.h"
#include <iostream>
#include "dog.h"
Dog::Dog(string dogName, string breed)
:dogName(dogName),
breed(breed){}
std::string Dog::Dog.getDogName(){
return dogName;
}
std::string Dog::Dog.getBreed(){
return breed;
}
and Dog.h:
#ifndef Dog_H
#define Dog_H
#include <iostream>
using namespace std;
class Dog{
public:
Dog(std::string dogName, std::string breed);
std::string getDogName();
std::string getBreed();
private:
std::string dogName;
std::string breed;
};
#endif
Also, I just want to add that this is no homework. I'm used to java and I'm only trying to learn some C++ since I need it for future work.
EDIT: Updated the code
std::vector<Dog> dogCollection; // here im defining dogCollection, no error here!
There actually is an problem here - class Dog isn't known to the compiler at this point.
You can solve this by either including Dog.h before Person.h in Person.cpp, or better add an #include "Dog.h" at the top of Person.h.
This is incorrect (and unrequired):
dogCollection = new std::vector<Dog>; // Remove this line.
as dogCollection is not a std::vector<Dog>*.
This is also incorrect:
void Person::addDog(string dogName, string breed){
Dog *newDog = new Dog(dogName, breed);
dogCollection.push_back(newDog);
}
as dogCollection contains Dog instances, not Dog*. Change to:
void Person::addDog(string dogName, string breed){
dogCollection.push_back(Dog(dogName, breed));
}
There is a problem with all of constructors:
Person::Person(string name, string address, int age){
name=name;
address=address;
age=age;
}
This is assigning the argument name to itself: it is not assigning to the member name. Same for address and age and similarly for the constructors of the other classes. Use initializer list:
Person::Person(string name, string address, int age) :
name(name),
address(address),
age(age)
{}
This method does not return a std::string:
string Person::getDogInfo(int index){
}
EDIT:
Missing class qualifier:
std::vector<Dog> getDogs(){
return dogCollection; //dogCollection undefined error here
}
means this is just a free function, with no association to class Person and therefore no access to dogCollection.
Change to:
std::vector<Dog> Person::getDogs(){
return dogCollection;
}
There are several problems with your code, and most of the other answers have pointed them out - mostly regarding the use of new when it should not be used. (Are you a C# programmer, moving to C++?)
However, there are problems with the #include directives as well. As #Bo mentioned, since Person uses Dog, you should include that header in Person.h. But Person also uses vector so that header should be included there as well. So Person.h should start with...
#include <vector>
#include "Dog.h"
Then in Person.cpp you don't have to include those files.
As a general rule (you can learn about "forward declaration" later), any types referenced in a header should be #included in that header.
I have this snippet of the code
account.cpp
#include "account.h"
#include <iostream>
#include <string>
using namespace std;
Account::Account(string firstName, string lastName, int id)
: strFirstName(firstName), strLastName(lastName), nID(id) {}
void Account::printAccount(){
cout << strFirstName;
}
account.h
#include <string>
using std::string;
class Account{
private:
string strLastName; //Client's last name
string strFirstName; //Client's first name
int nID; //Client's ID number
int nLines; //Number of lines related to account
double lastBill;
public:
Account(string firstName, string lastName, int id);
void printAccount();
};
company.h
#ifndef CELLULAR_COMPANY_H
#define CELLULAR_COMPANY_H
#include <string>
#include <list>
#include <iostream>
#include "account.h"
using namespace std;
class Company {
private:
list<Account> listOfAccounts;
public:
void addAccount(string firstName, string lastName, int id) {
Account newAccount(firstName, lastName, id);
listOfAccounts.push_back(newAccount);
}
void printAccounts(){
for(list<Account>::iterator i = listOfAccounts.begin(); i != listOfAccounts.end(); ++i){
i.printAccount; //here bug
}
}
};
#endif // CELLULAR_COMPANY_H
main.cpp
#include "cellularcompany.h"
int main(){
Company newCompany;
newCompany.addAccount("Pavel", "Nedved", 11111);
newCompany.printAccounts();
return 0;
}
can somebody please explain what does my error mean? thanks in advance (I have it in company.h see comment there)
I have bug 'struct std::_List_iterator<Account>' has no member named 'printAccount'
You forgot the parentheses after printAccount(). Otherwise, it's not a method call. Also, you need to use the -> operator, since it's an iterator.
for(list<Account>::iterator i = listOfAccounts.begin();
i != listOfAccounts.end(); ++i)
{
i->printAccount(); // Note the ()!
// This is equivalent to (*i).printAccount();
}
Try to change i.printAccount; to i->printAccount();