Not getting proper output!! Can anyone explain, what is wrong? - c++

#include<iostream>
using namespace std;
class parent
{
public:
string parnt_name;
int age;
};
class child:public parent
{
public:
string chld_name;
int age_child;
child()
{
cout<<"Name of child"<<chld_name<<" and age is "<<age<<" his/her parent name is"<<parent::parnt_name<<"and age of parent is "<<parent::age<<endl;
}
};
int main()
{
child c1;
c1.parnt_name="bill";
c1.age=45;
c1.age_child=20;
c1.chld_name="emily";
return 0;
}
Output of the code is
Name of child and age is 1975241920 his/her parent name is and age of parent is 1975241920
I am learning inheritance and I tried writing a code the upper one but it is not showing proper output. I cannot configure out what's the problem in the code?

Object constructors are called upon its creation. Meaning that the child class's constructor is called in this line: child c1;. Now at this line, does it have any data? Since your not initializing the internal variables (the two integers) it will most often contain garbage values. This is why you get an output like that.
To perform what you need, you can either initialize the class by passing those information as arguments,
class parent
{
public:
parent(string name, int age) : parent_name(name), age(age) {}
string parnt_name;
int age;
};
class child : public parent
{
public:
string chld_name;
int age_child;
child(string parent_name, int parent_age, string child_name, int child_age)
: parent(parent_name, parent_age), child_name(child_name), age(child_age)
{
cout<<"Name of child"<<chld_name<<" and age is "<<age<<" his/her parent name is"<<parent::parnt_name<<"and age of parent is "<<parent::age<<endl;
}
};
// Now in the main function
int main()
{
child c1("bill", 45, "emily", 20);
return 0;
}
Or else have another function to print the data.
class child:public parent
{
public:
string chld_name;
int age_child;
child()
{
}
void print_data()
{
cout<<"Name of child"<<chld_name<<" and age is "<<age<<" his/her parent name is"<<parent::parnt_name<<"and age of parent is "<<parent::age<<endl;
}
};
int main()
{
child c1;
c1.parnt_name="bill";
c1.age=45;
c1.age_child=20;
c1.chld_name="emily";
c1.print_data();
return 0;
}
Note: Always initialize data before using them. It might cause you havoc later on.

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

Change Object type based on inheritance

I have the class Person:
class Person {
public:
int Age;
int ID;
};
And I have 2 classes: Adult and Child that inherit Person:
class Child : Person{
public:
Child();
void print_ms_child(){
cout << "I'm an child";
}
};
class Adult : Person{
public:
Adult();
void print_ms_Adult(){
cout << "I'm an adult";
}
};
I want to declare a Person Object
int main() {
Person my_Person;
my_Person.Age = 10;
my_Person.ID = 013272;
And then use conditions to set its type.
if(my_Person.Age > 18){
my_Person = new Adult(); // this won't work
}
else{
my_Person = new Child(); // this won't work
}
I suppose it it's posible but I don't know the right syntax for doing it (How do I do that?). (Sorry for posting code that won't even compile)
But also, I want to change from Child to Adult in case the Age changes (I'm not even sure that's possible).
my_Person.Age = 21;
my_Person = new Adult(); // this won't work
I would first define your class Person like this instead:
class Person {
int Age;
int ID;
protected:
Person(int age, int id): Age{age}, ID{id} {}
public:
virtual ~Person() = default;
};
That is, Person's constructor is made protected so that a class outside the hierarchy can't create a Person object, and its destructor is made virtual to make it suitable as a base class for a polymorphic type.
Then, both Child and Adult publicly inherit from Person, as you already have them. Their constructors end up calling Person's constructor with the same parametrization their constructors receive:
class Adult: public Person {
public:
Adult(int age, int id): Person(age, id) {}
// ...
};
class Child: public Person {
public:
Child(int age, int id): Person(age, id) {}
// ...
};
Finally, for creating objects that derived from Person, I would create the factory function below:
std::unique_ptr<Person> create_person(int age, int id) {
if (age < 18)
return std::make_unique<Child>(age, id);
else
return std::make_unique<Adult>(age, id);
}
This factory function creates a Child object if the to-create person's age is under 18. Otherwise, it creates an Adult object. This – determining the type of the object to create – is done at run time.
EDIT: You wondered how a Child object could become an Adult object after its age has reached 18 years old.
I would suggest making the state of a Person object immutable so that a fresh new object has to be created every time the age of a person is increased. This way, creating a new object from an existing one will be the only way to grow a Person's age and, at that moment, you will have the control to decide whether to create a Child or Adult object based on the new age.
For doing this, first, qualify the Age data member in Person as const (you can do the same with ID). Then, define the following Person's member function which always creates a new object (with the same ID) resulting from increasing a Person's object Age by one:
std::unique_ptr<Person> Person::increase_age() const {
return create_person(Age + 1, ID);
}
As you see, it delegates the creation of the object to the factory function, create_person(), already explained above. This member function can be called on both Child and Adult objects since it inherits from Person.
You cannot change the type of a variable after its declaration. C++ is a statically typed language. my_person is a Person. You cannot change that.

Cannot inherit data from parent class to child class in 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.

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/

Efficient way to copy data from instance of parent class into child class

I have class scene (from assimp library) and I extended it with some functions and made class sceneChild. Now I need to copy data from instance of scene into sceneChild instance. I know it is possible to write manually something like this: sceneChild.a=scene.a , sceneChild.b=scene.b ... or this.a=scene.a , this.b=scene.b in copy constructor. However something tells me that this can be done in few lines of code. Am I right? If so then how this can be done? Thank you!
I ask about it because I need to perform this copy operation not only with scene class but with many other classes that are full of data and therefore it will take too long to do it manually.
Example:
class Parent
{
public:
string name;
};
class Child: Parent
{
public:
int age;
};
int main()
{
Parent p;
p.name = "some name";
Child c(p); // some magic here so that data (in this case string "name")
//is copied from p to c so that c.name=="some name"
return 0;
}
I'm not famliar with the scene class, but generaly you can use initialization list in the constructor to initialize the parent class.
In your example you can use:
class Parent
{
public:
string name;
};
class Child: public Parent
{
public:
int age;
Child(Parent& p) : Parent(p) {}
};