Cannot inherit data from parent class to child class in C++ - c++

I am trying to inherit data from two parent classes of Employee and Student to a child class of Manager.I have created set and get functions of each class and i have created a show function in child class which will also show data of both parent classes.But when i make objects and call functions of set values and then show data, only the data of child class is shown.
Can anyone tell my why is that and how do i solve it? Thanks for any help.
Code is below:
class Employee{
protected:
string name;
int number;
public:
Employee(){
name = "";
number = 0;
}
void set_name(string a){
name = a;
}
void set_number(int a){
number = a;
}
string get_name(){
return name;
}
int get_number(){
return number;
}
};
class Student{
protected:
string school;
string degree;
public:
Student(){
school = "";
degree = "";
}
void set_school(string a){
school = a;
}
void set_degree(string a){
degree = a;
}
string get_school(){
return school;
}
string get_degree(){
return degree;
}
};
class Manager:protected Employee, protected Student{
protected:
string title;
int dues;
public:
Manager(){
title = "";
dues = 0;
}
void set_title(string a){
title = a;
}
void set_dues(int a){
dues = a;
}
string get_title(){
return title;
}
int get_dues(){
return dues;
}
void show_data(){
cout << Employee::get_name();
cout << Employee::get_number() << endl;
cout << Student::get_school() << endl;
cout << Student::get_degree() << endl;
cout << get_title() << endl;
cout << get_dues() << endl;
}
};
int main(){
Employee emp;
Student stu;
Manager man;
emp.set_name("Fahad");
emp.set_number(10);
stu.set_school("COMSAT");
stu.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}

You have 3 different objects, each contains its own data!
For example, your manager class contains all attributes from manager, employee and student. In your main function:
Employee emp;
Student stu;
Manager man;
emp.set_name("Fahad");
emp.set_number(10);
stu.set_school("COMSAT");
stu.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
you only set some of the attributes of your objects. For manager, you only set title and dues. If you want to set also the name, you have to do it!
BTW: there is no need to use Student::get_school() to access the members of parent classes if you have not used the same attribute name multiple times or inherit multiple times from the same class.
I believe you want to do the following:
class Manager:public Employee, public Student{ ... };
int main(){
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
If you change to public for deriving from your parent classes, you can directly access the getter/setter functions from the object as you can see. As you have already getter and setter functions, it is a good idea to make the member vars now private.
BTW: The return value of main is typically 0 to tell that there is no error. If you want to return with "no error", you can simply omit the return statement. main() will than return 0 by default.

The following lines create three objects.
Employee emp;
Student stu;
Manager man;
The emp object is not related to the Employee sub-object of man and the stu object is not related to the Student sub-object of man.
The lines
emp.set_name("Fahad");
emp.set_number(10);
change the state of the independent emp object. They don't change the state of the Employee sub-object of man.
You need to use:
int main(){
// Employee emp; Not needed
// Student stu; Not needed
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
to see the values set on the same object. However, to do that you need to change the inheritances of Manager. Use
class Manager : public Employee, public Student {
...
};

Your code does not work as expected because:
You allocate separate objects/instances of each Employee, Student and Manager, e.g. emp, stud and man and set the data on each separate instance (for example, the emp.set_name() will only affect the emp object, not the man object).
You print the data member of the man object which does not include the data set in emp and man.
I do not know what the ideas behind your code design is, I do recommend to leave out multiple inheritance as it quickly leads to unmaintainable code. But to get your example code to work, do the following:
Delete the allocation of emp and stu;
change the emp and stu variable names in the setter calls to man.
Change protected to public in the Manager declaration where Manager extends Student and Employee.
class Manager:public Employee, public Student{
int main(){
Manager man;
man.set_name("Fahad");
man.set_number(10);
man.set_school("COMSAT");
man.set_degree("BSCS");
man.set_title("Manager Title");
man.set_dues(100);
man.show_data();
return 1;
}
And you will get the output I assume you expect.

Related

I have problem with least privilege principle. incrementing a member when an object is created

I want to keep track of the number of students in my system so, My idea was to make a static datamember in the "StudentController" class called "_numOfStudents" and increment it with the Student's constructor but it didn't work so, I moved it into the "Student" class and made that when a Student object is created the number increment by the help of the constructor. The problem is: isn't it not the Student class's business to know how many students are there thus breaking the principle of least privilege. what can I do better to keep track of the student objects' count.
Student(string firstName, string lastName, int age,vector<float>&subjects)//Student conctructor
{
SetFirstName(firstName);
setLastName(lastName);
SetAge(age);
SetMarks(subjects);
this->m_id++;
StudentController::_numberOfStudents++;
}
class StudentController//this is where i declared the static data member
{
private:
list<Student> _students;
public:
static int _numberOfStudents;
StudentController() {};
StudentController(list<Student>& st) :_students(st) {};
}
}
};
int StudentController::_numberOfStudents = 0;
When you try to do StudentController::_numberOfStudents++; in the constructor, the StudentController class is not yet defined, therefore the compiler doesn't know about that class and its static member.
Maybe keeping track of the students shouldn't be the role of the Student class itself. Instead it should be the role of a separate Classroom object:
struct Student;
struct Classroom {
void add(Student&) {
m_count++;
}
size_t count() const { return m_count; }
private:
size_t m_count{0};
};
struct Student {
Student(Classroom& classroom) {
classroom.add(*this);
}
};
int main()
{
Classroom classroom;
Student alice{classroom};
Student bob{classroom};
assert(classroom.count() == 2);
}

Inheritance and accessing attributes

I am learning OOP in C++, and I have written this piece of code to learn more about inheritance.
#include<bits/stdc++.h>
using namespace std;
class Employee {
public:
string name;
int age;
int weight;
Employee(string N, int a, int w) {
name = N;
age = a;
weight = w;
}
};
// this means the class developer inherits from employee
class Developer:Employee {
public:
string favproglang; //this is only with respect to developer employee
// now we will have to declare the constructor
Developer(string name, int age, int weight, string fpl)
// this will make sure that there is no need to reassign the name, age and weight and it will be assigned by the parent class
:Employee(name, age, weight) {
favproglang = fpl;
}
void print_name() {
cout << name << " is the name" << endl;
}
};
int main() {
Developer d = Developer("Hirak", 45, 56, "C++");
cout << d.favproglang << endl;
d.print_name();
cout << d.name << endl; //this line gives error
return 0;
}
Here the developer class is inheriting from the employee class, but when I am trying to print the name of the developer from the main function cout << d.name << endl; I am getting this error 'std::string Employee::name' is inaccessible within this context.
I am not getting why I am getting this error? I have declared all the attributes as public in the parent class. This error is not their when I am trying to access the name from the developer class itself as you can see in the function print_help(). Moreover I can also print d.favproglang from the main function, but then why not d.name? Any help will be highly appreciated. Thank you.
This is because the default access control for inheritance is "private".
If you change this:
// this means the class developer inherits from employee
class Developer: Employee {
to this:
// this means the class developer inherits from employee
class Developer: public Employee {}
By default, class inheritance is "private" inheritance and struct inheritance is "public" inheritance. Private inheritance means public and protected members of the base class will be treated like private members by the child class.
You can override this default behaviour by explicitly writing public, private or protected in front of the base class name.
Search "c++ base class members access control" to learn more.
There are 2 solutions(straightforward) to this.
Solution 1
Replace the class keywords for both the Employee and Developer class with the keyword struct. Note even if you replace class keyword for Developer with struct and leave the class keyword as it is for Employee then also this will work.
Solution 2
Add the keyword public in the derivation list as shown in the next line:
class Developer:public Employee

Setters and getters across multiple classes? CPP

I'm having some trouble on my homework trying to figure out how I can use a setter function from my base class in a derived class. I'm not sure if I worded that correctly as I'm new to C++, but hopefully my code can explain it better!
class account{
private:
double balance;
protected:
int numwithdraws = 0;
public:
void Setbalance(int bal)
{
balance = bal + balance;
}
int Getbalance()
{
return balance;
}
};
class checking : public account {
public:
WriteCheck(int checknum,double amount)
{
cout<<"Check amount?"<<endl;
cin>>amount;
Setbalance(amount);
checknum++;
}
};
Inside my main function there's an option to make a withdrawal, usually that would mean my balance would go down so I'd have to figure out how to make this negative in my setbalance later, but
checking obj2;
obj2.WriteCheck(0,0);
cout<<"New Balance = "<<obj1.Getbalance()<<endl;
I took out a lot my code to narrow down where the problem point is, but I'll try to explain it better in words if what I wrote down for my code is confusing.
What I have in my base class account are a Setbalance and a Getbalance. In my derived class checking I'm trying to use the Setbalance function that's in my base class in my derived class function WriteCheck to change the amount of my private variable balance which is in my account base class.
The problem is when I use the Setbalance in my derived class function and call my Getbalance in main, it still ends up 0 and doesn't change the amount in variable balance.
I'm getting confused reading my own explanation, so I understand if it's hard to grasp what I'm trying to ask. If that's the case, please let me know so that I can try and explain further!
You're on the right track with what you're trying to achieve (calling a function in the base class from within the derived class). A derived class will generally have the functions that the base class has, so calling
checking obj2;
obj2.Getbalance()
Is perfectly fine. I made some syntax changes to your code so it can run. The only major change I made was set balance to 0 so there wouldn't be any undefined behavior.
#include <iostream>
using namespace std;
class account {
private:
double balance = 0;
protected:
int numwithdraws = 0;
public:
void Setbalance(int bal)
{
balance = bal + balance;
}
int Getbalance()
{
return balance;
}
};
class checking : public account
{
public:
void WriteCheck(int checknum, double amount)
{
cout << "Check amount?" << endl;
cin >> amount;
Setbalance(amount);
checknum++;
}
};
int main()
{
checking obj2;
cout << "New Balance = " << obj2.Getbalance() << endl;
return 0;
}

Cin and cout in a constructor

I'm told to read a name from a constructor (homework), however the class constructor is not supposed to take any parameters - something I find weird.
I have tried to simply put cout's and cin.getline's inside the constructor, butt that doesn't work. I don't get how I can read data from user inside a constructor that does not have any parameters. Is it even possible?
E.g
class Animal
{
private:
char name[20];
public:
Animal() { SOMEHOW READ NAME HERE WITHOUT CON. PARAMETER }
};
int main() {
Animal a1; // should ask for name and read it, add it to data
return 0;
}
#include <iostream>
#include <sstream>
class Animal
{
public:
Animal() : name()
{
// Not the best design approach.Just show it possible for the question.
std::cout << "Name of animal?" << std::endl;
std::getline(std::cin, name);
std::cout << name << std::endl;
}
private:
std::string name;
};
int main(int argc, char * argv[])
{
Animal a1; // should ask for name and read it, add it to data
return 0;
}
I believe the code below is self explanatory with comments to guide you. In object oriented, a class should contain setter and getter methods. I have created a class Animal with one private string variable name. In the constructor, I ask for a name and assign it to the name variable of the object which is being created. I then display the name using a method called getName() which returns the current object's name and it is also known as a getter method. I believe you are new to Object Oriented and I hope I have made these concepts understandable to you.
#include <iostream>
using namespace std;
class Animal
{
private:string name;
public: Animal() {
cout<<"Enter the animal's name?";
getline(cin,this->name); //sets the current obj's name (storing the value)
cout<<"The animal's name is "<<getName();
}
public: string getName(){ return this->name; } //return current obj's name value (getter method)
};
int main()
{
Animal a1;
//cout<<a1.getName(); //it will get the name of a1's object
return 0;
}
#include <iostream>
using namespace std; //Don't kill me
class animal
{
private:
char name [20];
public:
animal () //Constructor without parameters
{
cout<<"Please enter animal name: ";
cin>>name;
}
void getAnimal();
};
void animal :: getAnimal()
{
cout<<name;
}
int main ()
{
animal a1;
a1.getAnimal();
}
Remember that there are 3 types of constructors. In this case it seems that you have to use a default constructor which does require a parameter as it is just setting name to a default value. To get a user defined value you can use cin within the constructor. When you create an object in main and run your program it will allow the user to enter a name.
To read and print the name I found that a getter method was easier.
https://www.geeksforgeeks.org/constructors-c/

Classes with Arrays using other class objects

I have two completed classes at the moment, the Teacher and Student classes have default definitions.
Right now I am trying to figure out the Classroom and School classes. The Classroom class is supposed to hold a Teacher and an array of 35 Student objects.
The School class is supposed to contain an array of 100 Classroom objects.
How do I do this, I sort of know how to initialize an array in a class but I'm not sure how to achieve this using the objects of another class?
class Teacher
{
private:
string last;
string first;
int gradeLevel;
public:
Teacher();
};
Teacher::Teacher()
{
last = "AAAA";
first = "BBBB";
gradeLevel = 0;
}
class Student
{
private:
string studLast;
string studFirst;
public:
Student();
};
Student::Student()
{
studLast = "AAAA";
studFirst = "BBBB";
}
class Classroom
{
};
class School
{
};
For example:
class Classroom
{
private:
Teacher t; // create a teacher
Student s[35]; // create an array of 35 students
...
};
class School
{
private:
Classroom rooms[100]; // create an array of 100 rooms
...
};
What you want to do here is create a Teacher, just one like you wanted, and then create an array of Student objects, which if you didn't know is done like Student students[35];. Then to the School object which is just an array of Classroom objects. Here is the full code:
class Classroom
{
private:
Teacher teacher;
Student students[35];
public:
Classroom();
};
Classroom::Classroom()
{
;
}
class School
{
private:
Classroom classrooms[100];
public:
School();
};
School::School()
{
;
}
Note: all of the items in the arrays are initialized when you write something like Student students[35];. You can check this by doing cout << this->stduents[12].studLast << endl;