Defining a vector within a custom class - c++

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.

Related

How to declare getters/setters for an array member variable [duplicate]

This question already has answers here:
How do I write setters and getters for an array? (c++)
(3 answers)
Closed 3 years ago.
I'm trying to represent a Course with Students. The Students have information about their first and last names, age... And the Courses have a name and an array of 3 Students.
I'm getting an error when I try to define the getters and setters for the array.
Error (active) E0415 no suitable constructor exists to convert from "Student [3]" to "Student"
Error (active) E0137 expression must be a modifiable lvalue
Course.h
#pragma once
#include "Student.h"
#include "Teacher.h"
class Course
{
private:
string name;
Student students[3];
Teacher teacher;
public:
Course();
~Course();
void setName(string name);
string getName();
void setStudents(Student students[3]);
[3] Student getStudents();
};
Course.cpp
#include <iostream>
#include "Course.h"
#include "Student.h"
#include "Teacher.h"
using namespace std;
Course::Course() {}
Course::~Course()
{
}
void Course::setName(string name)
{
this->name = name;
}
string Course::getName()
{
return this->name;
}
void Course::setStudents(Student students[3])
{
/*for (int i = 0; i < 3; i++) {
this->students[i] = students[i];
}*/
//This way the set works
this->students = students;
}
[3]Student Course::getStudents()
{
return this->students;
}
I expect the output of the get to be the array of students.
A C style array cannot be copied, cannot be automatically assigned, and cannot be returned from a function.
Thankfully, the C++ standard library provides a thin wrapper class over C style arrays which implement all these operations. It’s called std::array and it can be used exactly like you’re trying to use C-style arrays.
#pragma once
#include "Student.h"
#include "Teacher.h"
#include <array>
class Course
{
private:
string name;
std::array<Student, 3> students;
Teacher teacher;
public:
Course();
~Course();
void setName(string name);
string getName();
void setStudents(std::array<Student, 3> students);
std::array<Student, 3> getStudents();
};

Undefined reference to Class::Class/Function (Beginner in OOP)

I have this annoying error;
Undefined Reference to Shape::Shape(...), Shape::getName(...), Shape::getAge(...)
My Main.cpp is this
#include <iostream>
#include <string>
#include "Bit.h"
using namespace std;
int main()
{
//simple assignment
string name;
int age;
cout<<"enter name: ";
cin>>name;
cout<<"enter age: ";
cin>>age;
Shape sh(name,age); //class declaration (i think here is the problem)
cout<<endl<<"name: "<<sh.getName();
cout<<endl<<"age: "<<sh.getAge();
return 0;
}
This is the Bit.h header
#include <iostream>
#include <string>
using namespace std;
#ifndef BIT_H
#define BIT_H
//creating class
class Shape{
string newName;
int newAge;
public:
//Default Constructor
Shape();
//Overload Constructor
Shape(string n,int a);
//Destructor
~Shape();
//Accessor Functions
string getName();
int getAge();
};
And finally, this is the Bit.cpp
#include "Bit.h"
//constructors and destructor
Shape::Shape(){
newName="";
newAge=0;
}
Shape::Shape(string n, int a){
newName=name;
newAge=age;
}
Shape::~Shape(){
}
string Shape::getName(){
return newName;
}
//getters
int Shape::getAge(){
return newAge;
}
I understand, that this might be a very simple problem/error, but I have been struggling for about 2 hours.
I suppose that the error is in the declaration od "sh" object, even if I declare it like this "Shape sh();" or "Shape sh;", there are still errors.
Thanks
EDIT. GNU GCC Compiler
EDIT2. Using Code Blocks (sorry for forgetting all these)
You're probably not compiling Bit.cpp, but only Main.cpp.
Considering that Bit.h, Bit.cpp and Main.cpp are in the same folder, here is how you should compile it :
g++ *.cpp
It will still not compile, as in the default constructor, you're trying to initialize name, and age which both don't exist.
You probably meant newAge, and newName?
In the other Constructor, name and age also don't exist, you probably meant n, and a?

Error creating a class object

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;
}

expected class name before '{' token. C++ inheritance

I've spent quite a few hours researching and trying to figure out why I'm getting this error. Basically the three files that have to do with the inheriting are CollegeMember.h, Employee.h, and EmpAcademicRecord.h. Employee. is inheriting from CollegeMember.h and EmpAcademicRecord.h is inheriting from Employee.h. Like this CollegeMember <- Employee <- EmpAcademicRecord. The error occurs in EmpAcademicRecord.h. Heres the three files.
CollegeMember.h
#include <cstdlib>
#include <iostream>
#include<ctype.h>
#include<string.h>
#include "Employee.h"
#include "Student.h"
using namespace std;
// ****************************************************************************
// Class Definitions follow
typedef char* String;
// The CollegeMember class
class CollegeMember
{
protected:
int ID_Number;
string FirstName, LastName;
string AddressLine1, AddressLine2, StateProv, Zip;
string Telephone;
string E_Mail;
string answer, answer2, answer3, answer4;//used as sort of booleans for use with validation
// member functions
public:
CollegeMember ( ); // constructor
CollegeMember(const CollegeMember&); //overloaded constructor
void Modify (CollegeMember Member);
void InputData(int x);
string Summary ( ); //summary
string PrintMe(); //fully describes
}; // End of CollegeMember class declaration
Employee.h
#include <cstdlib>
#include <iostream>
#include<ctype.h>
#include<string.h>
#include "EmpAcademicRecord.h"
#include "EmpEmploymentHistory.h"
#include "EmpExtraCurricular.h"
#include "EmpPersonalInfo.h"
#include "EmpPublicationLog.h"
using namespace std;
// ****************************************************************************
// Class Definitions follow
typedef char* String;
// The Employee Class
class Employee: protected CollegeMember
{
float Salary;
protected:
string Department, JobTitle;
// Member Functions
public:
Employee ( ); // constructor
void Modify (Employee ThisEmp);
void InputData(int x);
void SetSalary (float Sal) // Specified as an in-line function
{ Salary = Sal;}
float GetSalary ( ) {return Salary;} // Specified as an in-line function
string Summary ( ); //summary
string PrintMe(); //fully describes
}; // End of Employee class declaration
EmpAcademicRecord.h
#include <iostream>
#include <cstdlib>
#include<ctype.h>
#include<string.h>
using namespace std;
typedef char* String;
class EmpAcademicRecord: protected Employee{ //error occurs on this line
protected:
int ReferenceNumber;
string Institution;
string Award;
string start;
string end;
public:
EmpAcademicRecord();
void InputData (int x);
void Modify(EmpAcademicRecord ThisRec);
void Summary();
};
Any help with this would be greatly appreciated.
That sort of error is usually caused by the type not being defined when you try to use it.
In this case, it appears that you may have included EmpAcademicRecord.h without having first included Employee.h (the includes at the top of the former do not show the latter).
In other words, at the point where the compiler sees:
class EmpAcademicRecord: protected Employee { //error occurs on this line
it has no idea what the Employee class is.
It may be a simple matter of adding:
#include "Employee.h"
to the top of that file, it's a little difficult to be certain since we don't have the code files. In any case, it's certainly a good first step.
Since you have EmpAcademicRecord.h being included by Employee.h, that will probably result in an infinite recursion.
You could fix that with include guards, but I can't see why you need that particulat inclusion. EmpAcademicRecord depends on Employee, not the other way around.

Can the constructor be defined out of the class?

Why gcc cannot compile successful of the codes below?
Can the constructor be defined out of the class?
#include <string>
using std::string;
class Person{
public:
Person(const string &a, const string &b);
private:
string name, address;
};
Person::Person(const string &a, const string &b){
name(a);
address(b);
}
Thanks!
Because neither name nor address are callable. You probably meant to put them into a member-initializer-list.
Person::Person(const string &a, const string &b)
: name(a), address(b)
{
}
Your syntax is wrong:
Person::Person(const string &a, const string &b) : name(a), address(b) {}
You just wrote it wrong. It should be:
Person::Person(const string &a, const string &b) : name(a), address(b) { }
In principle, and very much in practice, too, you can and should define member functions outside the class definition to decouple the code base and reduce compile times.
This is called separation of implementation and declaration. It is actually a good idea to keep your implementations separately, in a cc or cpp file.
Thus, in your header:
//Person.h
#ifndef PERSON_H // <---- include header guards in your headers
#define PERSON_H
#include <string>
//using std::string; <--- you should remove this line, you don't want to import namespaces
// in your header file, or else they are imported in all
// files including this header
class Person{
public:
Person(const std::string &a, const std::string &b);
private:
std::string name, address; // qualify your names in the header
};
#endif
and your implementation file:
//Person.cpp
#include "Person.h"
using namespace std; // <---- if you wish, import the std namespace in your global namespace
// in the implementation file
Person::Person(const string &a, const string &b):
name(a), // <---- correct syntax of initializer lists
address(b)
{
}