Errors in class relationships in c++ - c++

I am quite new to the concept of class relationships and wrote a program to test it out. However, it is giving me some errors.
There are 5 header files for classes University,Dept,Teacher,Student and Course and a .cpp file involved. I have implemented composition between University and Dept and bidirectional association between Dept and Student, Teacher, Course
uni.h
#pragma once
//#include"dept.h"
class University
{
public:
University(string,int);
void setDepartmentName(string,int);
Dept* getDeptAddress(int);
~University();
private:
Dept* departments;
int totalDepts;
string name;
};
University::University(string name1,int num) :name(name1)
{
departments = new Dept[num];
totalDepts=num;
}
void University::setDepartmentName(string name,int depNo)
{
departments[depNo].setName(name);
}
Dept* University::getDeptAddress(int i)
{
return &(departments[i]);
}
University::~University()
{
delete[] departments;
}
dept.h
#pragma once
//class Student;
//class Teacher;
//class Course;
#include"course.h"
#include"teacher.h"
#include"student.h"
class Dept
{
public:
Dept();
string getName();
void setName(string);
~Dept();
private:
Student** students;
Course** courses;
Teacher** teachers;
string name;
int noOfStudents, noOfTeachers, noOfCourses;
};
Dept::Dept()
{
}
string Dept::getName() {
return name;
}
void Dept::setName(string name1) {
name = name1;
}
Dept::~Dept()
{
}
course.h
#pragma once
class Dept;
//#include"dept.h"
class Course
{
public:
Course(string, string);
void assignDept(Dept*);
string getDeptName();
~Course();
private:
Dept* department;
string code;
string name;
};
Course::Course(string code1, string name1) :code(code1), name(name1)
{}
void Course::assignDept(Dept * dep)
{
department = dep;
}
string Course::getDeptName()
{
//statement giving error: 'Use of undefined type 'Dept'' & 'left of -> must point to class'
return department->getName();
}
Course::~Course()
{}
student.h
#pragma once
#include"dept.h"
class Student
{
public:
Student(string,string);
void assignDept(Dept*);
string getDeptName();
~Student();
private:
Dept* department;
string rollNo, name;
};
Student::Student(string rNo,string name1):name(name1),rollNo(rNo)
{}
void Student::assignDept(Dept *dep)
{
department = dep;
}
string Student::getDeptName()
{
//statement giving error: 'Use of undefined type 'Dept'' & 'left of -> must point to class'
return department->getName();
}
Student::~Student()
{
}
teacher.h
#pragma once
//#include"dept.h"
class Teacher
{
public:
Teacher(string);
void assignDept(Dept*);
string getDeptName();
~Teacher();
private:
Dept* department;
string name;
};
Teacher::Teacher(string name1) :name(name1)
{}
void Teacher::assignDept(Dept *dep)
{
department = dep;
}
string Teacher::getDeptName()
{
//statement giving error: 'Use of undefined type 'Dept'' & 'left of -> must point to class'
return department->getName();
}
Teacher::~Teacher()
{
}
source.cpp
#include<iostream>
using namespace std;
#include<string>
#include"dept.h"
#include"course.h"
#include"teacher.h"
#include"student.h"
#include"uni.h"
int main()
{
University u1("FAST",3);
u1.setDepartmentName("CS", 0);
u1.setDepartmentName("EE", 1);
u1.setDepartmentName("CV", 2);
Student s1("l144049", "Syed Abdul Wahab");
Course c1("cs1", "ITC");
Teacher t1("abc");
c1.assignDept(u1.getDeptAddress(0));
t1.assignDept(u1.getDeptAddress(1));
s1.assignDept(u1.getDeptAddress(2));
cout << c1.getDeptName()<<endl;
cout << t1.getDeptName() << endl;
cout << s1.getDeptName() << endl;
cin.get();
return 0;
}
However, if i #include 'dept.h' in student.h, course.h and teacher.h, it gives me errors on 'Dept' namely 'identifier 'Dept' is undefined'.
Any help would me greatly appreciated!

The problem is you have a circular dependency: teacher.h includes dept.h which includes teacher.h. This can't work.
To fix it, use "forward declarations" in your header files, and move your implementations to .cpp files.

Related

C++ Can not manage to display the class datatype array

This is the code I wrote, total beginner
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
public:
string ID;
string name;
string surname;
string department;
string email;
public:
//get and set functions for ID, Name, Surname, Department, Email properties
string getID()
{
return this->ID;
};
void setID(string _ID)
{
this->ID = _ID;
};
string getName()
{
return this->name;
};
void setName(string _name)
{
this->name = _name;
};
string getSurname()
{
return this->surname;
};
void setSurname(string _surname)
{
this->surname = _surname;
};
string getDepartment()
{
return this->department;
};
void setDepartment(string _department)
{
this->department = _department;
};
string getEmail()
{
return this->email;
};
void setEmail(string _email)
{
this->email = _email;
};
};
//inherit Student class from Person class
class Student :public Person
{
private:
int student_counter = 0;
public:
//constructor
Student()
{
};
Student(string id, string Name, string Surname, string Department, string Email)
{
setID(id);
setName(Name);
setSurname(Surname);
setDepartment(Department);
setEmail(Email);
}
//student add
void addStudent(string id, string Name, string Surname, string Department, string Email)
{
if (student_counter >= 100)
{
cout << "cant add more students";
}
else
{
Student _S[100]
Student newS;
newS.setID(id);
newS.setName(Name);
newS.setSurname(Surname);
newS.setDepartment(Department);
newS.setEmail(Email);
_S[student_counter] = newS;
student_counter++;
}
}
//display students
void display()
{
for (int i = 0; i < student_counter; i++)
{
cout << _S[i].getID() << " - ";
}
}
};
};
int
main()
{
Student stu;
stu.addStudent("ST123456", "Ege", "Inan", "CS", "ege # gmail.com");
stu.display();
}
The problem is here
//inherit Student class from Person class
class Student :public Person
{
private:
int student_counter = 0;
public:
//constructor
Student()
{
};
Student(string id, string Name, string Surname, string Department, string Email)
{
setID(id);
setName(Name);
setSurname(Surname);
setDepartment(Department);
setEmail(Email);
}
//student add
void addStudent(string id, string Name, string Surname, string Department, string Email)
{
if (student_counter >= 100)
{
cout << "cant add more students";
}
else
{
Student _S[100];
Student newS;
newS.setID(id);
newS.setName(Name);
newS.setSurname(Surname);
newS.setDepartment(Department);
newS.setEmail(Email);
_S[student_counter] = newS;
student_counter++;
}
}
//display students
void display()
{
for (int i = 0; i < student_counter; i++)
{
cout << _S[i].getID() << " - ";
}
}
};
};
The error message I get is this:
main.cpp:106:9: error: ‘_S’ was not declared in this scope
106 | cout<<_S[i].getID()<<" - ";
| ^~
I tried moving the definition of Student _S to the private part of student class like this:
class Student :public Person
{
private:
int student_counter = 0;
Student _S[100];
public:
//constructor
Student()
{
};
Student(string id, string Name, string Surname, string Department, string Email)
{
setID(id);
setName(Name);
setSurname(Surname);
setDepartment(Department);
setEmail(Email);
}
//student add
void addStudent(string id, string Name, string Surname, string Department, string Email)
{
if (student_counter >= 100)
{
cout << "cant add more students";
}
else
{
Student newS;
newS.setID(id);
newS.setName(Name);
newS.setSurname(Surname);
newS.setDepartment(Department);
newS.setEmail(Email);
_S[student_counter] = newS;
student_counter++;
}
}
//display students
void display()
{
for (int i = 0; i < student_counter; i++)
{
cout << _S[i].getID() << " - ";
}
}
};
};
But then I got this:
65 | Student _S[100];
| ^~
main.cpp:61:7: note: definition of ‘class Student’ is not complete until the closing brace
61 | class Student:public Person
| ^~~~~~~
What would be the best way of handling this? where to define the array to get the program to run as intended?
In the first code, _S is a local variable inside of addStudent(), so display() can't access it.
Your second code is better, in that display() can now access _S. But a Student object can't hold any data members that are also Student objects, you would end up with an endless recursive allocation.
To accomplish what you want, you need to make _S, student_counter, addStudent(), and display() be static members of the Student class, eg:
class Student :public Person
{
private:
static int student_counter;
static Student _S[100];
public:
//constructor
Student()
{
};
Student(string id, string Name, string Surname, string Department, string Email)
{
setID(id);
setName(Name);
setSurname(Surname);
setDepartment(Department);
setEmail(Email);
}
//student add
static void addStudent(string id, string Name, string Surname, string Department, string Email)
{
if (student_counter >= 100)
{
cout << "cant add more students";
}
else
{
Student newS;
newS.setID(id);
newS.setName(Name);
newS.setSurname(Surname);
newS.setDepartment(Department);
newS.setEmail(Email);
_S[student_counter] = newS;
student_counter++;
}
}
//display students
static void display()
{
for (int i = 0; i < student_counter; i++)
{
cout << _S[i].getID() << " - ";
}
}
};
int Student::student_counter = 0;
Student Student::_S[100];
int main()
{
Student::addStudent("ST123456", "Ege", "Inan", "CS", "ege # gmail.com");
Student::display();
}
Online Demo

error c2084 on all my methods but each method only has one body

Only one of my classes are having this problem, it keeps saying error c2084, see previous definition which takes me to the same spot where the error is.
Here's my .h file
//PersonalInfo header file
#ifndef PERSONALINFO_H
#define PERSONALINFO_H
#include <string>
class PersonalInfo {
private:
std::string firstName;
std::string lastName;
int age;
std::string phoneNumber;
public:
//default constructor
PersonalInfo();
//copy constructor
PersonalInfo(const PersonalInfo&) = default;
//getters
std::string getFirstName();
std::string getLastName();
int getAge();
std::string getPhoneNumber();
//setters
void setFirstName(std::string name);
void setLastName(std::string name);
void setAge(int num);
void setPhoneNumber(std::string number);
};
#include "PersonalInfo.cpp"
#endif
Here's my .cpp, as you can see, they are only defined once but the error says they are defined already.
This website is making me add more info to post but there is no more info on this error to give so now im just typing until it lets me post
#include "PersonalInfo.h"
//default constructor
PersonalInfo::PersonalInfo() {
firstName = "";
lastName = "";
age = -1;
phoneNumber = "";
}
//getters
std::string PersonalInfo::getFirstName() {
return firstName;
}
std::string PersonalInfo::getLastName() {
return lastName;
}
int PersonalInfo::getAge() {
return age;
}
std::string PersonalInfo::getPhoneNumber() {
return phoneNumber;
}
//setters
void PersonalInfo::setFirstName(std::string name) {
firstName = name;
}
void PersonalInfo::setLastName(std::string name) {
lastName = name;
}
void PersonalInfo::setAge(int num) {
age = num;
}
void PersonalInfo::setPhoneNumber(std::string number) {
phoneNumber = number;
}
Remove the #include "PersonalInfo.cpp" at the end of the .h file. You're creating a circular include chain between two files and it makes everything duplicated. Your .cpp files should #include your .h files, not the other way around.

Call function in vector of 2 class inheritance

I'm getting into polysorphism. I'm in trouble with vector when I call function. This is my code:
Class Customer:
#pragma once
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Customer
{
protected:
string id;
float money;
public:
Customer();
~Customer();
virtual void Input();
virtual void Output();
string GetId()
{
return id;
}
void SetId(string ID)
{
id = ID;
}
};
Class LoyalCustomer:
#pragma once
#include"Customer.h"
class LoyalCustomer:public Customer
{
int level; //level of relationship
public:
LoyalCustomer();
~LoyalCustomer();
void Input();
void Output();
};
RegularCustomer:
#pragma once
class RegularCustomer:public Customer
{
public:
RegularCustomer();
~RegularCustomer();
void Input();
void Output();
};
Class SuperMarket:
#pragma once
#include"LoyalCustomer.h"
#include"RegularCustomer.h"
class SuperMarket
{
vector<Customer*> list;
public:
SuperMarket();
~SuperMarket();
void FindCustomer()
{
string ID;
cout << "Input id of customer: ";
cin >> ID;
for (int i = 0; i<list.size(); i++)
if (ID == list[i]->GetId())
{
//do something
}
}
void Input()
{
string ID;
cout << "Input id of customer: ";
cin >> ID;
Customer *p = NULL;
if (ID[0] == 'L')
{
p = new LoyalCustomer;
p->Input();
p->SetId(ID);
list.push_back(p);
}
if (ID[0] == 'R')
{
p = new RegularCustomer;
p->Input();
p->SetId(ID);
list.push_back(p);
}
}
void Output()
{
//printf customer
}
};
When I call GetID() function in FindCustomer() function in line:if (ID == list[i]->GetId()) and then I run my code, program doesn't notify error but I input "ID" to find, it doesn't find out. I don't know how to fix it. Please help me. Thanks!
Try compare string like ID.compare(list[i]->GetId()) == 0

C++ classes query error : left of "" must point to class/struct/union

I'm trying to implement a class called Person that consists of the members : name , gender and ads where ads is of a class type called Address that consists of the members street , tel and PObox. When i compile the program i get an error for whenever i try to call ads inside any of the Person implementations (although the syntax should be correct) . I have attached the address.h , person.h ,implementation for Person and implementation for Address files .
address.h
#include<iostream>
class Address
{
public:
Address();
char* getstreet();
char* gettel();
int getpobox();
void setall(char *str , char *tel , int pobox);
void print();
/*~Address();*/
private:
char* street;
char* tel;
int POBox;
};
person.h
#include <iostream>
#include "address.h" // header file for the Address class
#include "gender.h" // header file for the Gender enum
using namespace std;
class Person
{
public:
Person();
Person(char *n, Gender *g, Address *ad);
Person(const Person &f);
void setName(char * n);
void setAds( Address *ad);
char *getName();
/*Address *getAds();*/
/*~Person();*/
void print();
private:
char *name;
Gender *gender;
Address *ads;
};
Implementation 2.cpp
#include<iostream>
#ifndef address_h
#define address_h
#include"address.h"
using namespace std;
//IMPLEMENTATION OF ADDRESS FUNCTIONS
Address::Address()
{
street = "default street";
tel = "55555555";
POBox = 1315425;
}
char* Address::getstreet()
{
return street;
}
char* Address::gettel()
{
return tel;
}
int Address::getpobox()
{
return POBox;
}
void Address::setall(char *str , char *tel2 , int pobox)
{
street = str;
tel = tel2;
POBox = pobox;
}
void Address::print()
{
cout<<"Street : "<<street<<endl;
cout<<"Telephone : "<<tel<<endl;
cout<<"PO box : "<<POBox<<endl;
}
#endif
Implementation.cpp
#ifndef person_h
#define person_h
#include<string>
#include<iostream>
#include"address.h"
#include"person.h"
using namespace std;
//IMPLEMENTATION OF PERSON FUNCTIONS
Person::Person()
{
(*gender) = female;
name = "testname";
(*ads).setall("random adress","0503216532",95421);
}
Person::Person(char *n, Gender *g, Address *ad) //copy constructor
{
n = name;
g = gender;
ad->setall("cpyconstruct test","42324134",14925);
}
Person::Person(const Person &f)
{
name = f.name;
gender = f.gender;
ads = f.ads;
}
void Person:: setName(char * n)
{
n = "karim (TESTING SETNAME)";
}
void Person::setAds(Address *ad)
{
ads->setall("aus","04314013",14314);
}
char* Person::getName()
{
return name;
}
void Person:: print()
{
cout<<"Name : "<<name<<endl;
if(gender == 0)
{
cout<<"gender : male"<<endl;
}
else
cout<<"gender : female"<<endl;
ads->setall("hello","056323453",1995);
}
#endif
ads is an uninitialized pointer, so you can't do anything with it (say, by using the -> operator).
Solution: initialize with new in Person's ctor; or, better yet, don't use a pointer at all. You don't need one.
class Person
{
...
Address ads;
};
Person::Person()
{
(*gender) = female;
name = "testname";
ads.setall("random adress","0503216532",95421);
}
...and crashmaster's right: when you get ads working, you're going to get memory problems with Address's members. Use std::string and they'll be taken care of, too.

Class Constructor error, class "classname" has no member "classname"

#ifndef RESERVATIONS_H_INCLUDED
#define RESERVATIONS_H_INCLUDED
#include <vector>
#include <string.c>
class Reservations
{
public:
Reservations::Reservations { }
Reservations(string FullName, int PhoneNum);
string getname() { return FullName; }
int getnumber() { return PhoneNum; }
private:
string FullName;
int PhoneNum;
}
#endif // RESERVATIONS_H_INCLUDED
Reservations::Reservations(string FullName, int PhoneNum) //error on this line
{
FullName = FullName;
PhoneNum = PhoneNum;
}
I get the error in the title, I don't know why it's assuming I want it to have a member of it's own class...
you included wrong header file
Change
#include <string.c>
to
#include <string>
Also use string with full namespace std.
below code should compile with minor fix:
class Reservations
{
public:
Reservations() : PhoneNum(0) {}
Reservations(std::string FullName, int PhoneNum);
std::string getname() { return FullName; }
int getnumber() { return PhoneNum; }
private:
std::string FullName;
int PhoneNum;
};
Reservations::Reservations(std::string FullName, int PhoneNum)
{
this->FullName = FullName;
this->PhoneNum = PhoneNum;
}
// Better use member initializers list
Reservations::Reservations(std::string FullName, int PhoneNum)
: FullName(FullName),
PhoneNum(PhoneNum)
{
}
Do you mean
Reservations::Reservations() { }
instead of
Reservations::Reservations { }
?
Do this:
class Reservations
{
public:
//Reservations::Reservations { }
Reservations() { }
....