Cin and cout in a constructor - c++

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/

Related

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

#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.

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.

cpp access subclass object methods from function that requires superclass object

I have written the following code:
// constructors and derived classes
#include <iostream>
using namespace std;
class Mother
{
public:
int age;
Mother()
{
cout << "Mother: no parameters: \n"
<< this->age << endl;
}
Mother(int a)
{
this->age = a;
}
void sayhello()
{
cout << "hello my name is clair";
}
};
class Daughter : public Mother
{
public:
int age;
Daughter(int a)
{
this->age = a * 2;
};
void sayhello()
{
cout << "hello my name is terry";
}
};
int greet(Mother m)
{
m.sayhello();
}
int main()
{
Daughter kelly(1);
Son bud(2);
greet(kelly);
}
and my question is this:
Since kelly is an instances of a class derived from Mother it makes sense to me that I can pass it into a function that requires an object of type mother ie. greet. My question is this, is it possible to call the sayhello function from within greet such that it will say
it will say "hello my name is terry" instead of "hello my name is clair".
What you're asking for is called "polymorphic behavior" (or "dynamic dispatch") and it is a basic feature of C++. To enable it, you'll need to do a couple of things:
Tag your sayhello() methods with the virtual keyword (i.e. virtual void sayhello() rather than just void sayhello())
Change the greet() method's argument to pass-by-reference or pass-by-pointer, to avoid object-slicing problems (i.e. int greet(const Mother & m) rather than int greet(Mother m))
Once you've done that, the compiler will intelligently choose which sayhello() method to call at run-time, based on the m argument's actual object-type, rather than hard-coding the choice at compile-time based on the type explicitly listed in the greet function's arguments-list.

Issues with classes and static variables

I am having troubles wrapping my head around the use of static class variables, and what exactly to include within the main file, as opposed to the function file. When I try to compile my code I get a huge number of errors.
The question provided requires me to create a static ID variable that is incremented by each new animal (e.g. Elephant and Cheetah), so elephant would display ID 1 and cheetah ID 2. I know my animal.h file is correctly formatted, but I am unsure about the main and animal.cpp files.
Could someone please correct any issues that are present within my code? Thanks!
animal.h
#include <iostream>
#include <string>
using namespace std;
#ifndef ANIMAL_H
#define ANIMAL_H
class animal{
public:
animal();
animal(string aSpecies); //Animals are allocated a unique ID on
//creation,
//the first animal has ID 1, second is 2
//and so on
void set_name(string aName); //Change the animals name
string get_species();
string get_name();
std::string name;
std::string species;
int get_ID(); //The animals unique ID
static int currentID; //The next ID number to give out
~animal();
};
#endif //ANIMAL_H
animal.cpp
#include <iostream>
#include "animal.h"
using namespace std;
//static ID variable
int animal::currentID = 0 ;
//Default animal constructor implementation
animal::animal(){
name = "?";
currentID++;
}
animal::animal(string aSpecies){
species = aSpecies;
}
void animal::set_name(string aName){
name = aName;
}
std::string animal::get_species(){
return species;
}
std::string animal::get_name(){
return name;
}
main-1-1.cpp
#include <iostream>
#include "animal.h"
using namespace std;
int main(){
animal Elephant;
animal Cheetah;
Elephant.set_name("Katrina");
Cheetah.set_name("Alex");
cout << Elephant.get_name() << " " << animal::currentID <<endl;
cout << Cheetah.get_name() << " " << animal::currentID << endl;
return 0;
};
There is some syntax to correct
The static member variable has the classes namespace, so in main you also have to call it with
animal::currentID
Then, new returns a pointer, so Elephant and Cheetah should be declared like
animal* Elephant;
animal* Cheetah;
Elephant = new animal("Elephant");
Cheetah = new animal("Cheetah");
However, there is no reason to use pointers here, just do
animal Elephant("Elephant");
animal Cheetah("Cheetah");
Also, the default constructor has not been defined in the classes body, you have to add
animal();
to the class declaration.
The members name and species are missing in the class body, too so make sure to add
private:
std::string name, species;
to the class body
There is no << operator for animal yet, so the output does not know what to do. You can add them to the class or output only the species member of the animal. Overloading the operator would look like this
std::ostream& operator<<(std::ostream &os, animal const &A){
os << "The animal " << A.name << " is of species " << A.species
<< " and has ID " << A.myID;
};
And you typically declare it as a friend non-member, so add
friend std::ostream& operator<<(std::ostream &os, animal const &A);
to the class body, this allows the operator to access the private members of animal. Note that this requires <iostream> for animal to work. You can then do
std::cout << Cheetah << std::endl;
And it will print the description of Cheetah.
Some further advice:
Having using namespace in a header file is a dangerous thing, it might bring things into scope that you are not aware of.
From the code you posted, currentID has no reason to be a member of animal, it can just be a local variable in main. If you want to keep track automatically, you can add a non-static member myID and increment the ID upon construction like this
class animal{
public:
animal::animal():myID(++currentID){};
private:
static int currentID;
int myID`
};
int animal::currentID = 0;
It looks like you are declaring the static variable correctly and setting it to zero. However, you need to increment it in the constructors (animal::animal).
The other issue is that you are using the new keyword to allocate two animals on the heap, but then you are assigning the pointers to animal objects. Here are two ways you could handle this instead instead:
animal Elephant("Elephant"); // Not on the heap
OR
animal *Elephant = new animal("Elephant"); // Elephant is a pointer to an object on the heap
Another thing, std::cout has no way of knowing how to print these objects. Instead of printing them directly, you should call one of your get_ functions:
cout << "The animal " << Elephant.get_species() << ... ;
Finally, if you want to be able to access the ids of the animals, you need to store the ids as member variables and use the static id variable as an incremented to ensure that every animal has a unique, consecutive id.

using pointers with inheritance in C++

I have a problem in understanding one important aspect of the c++. see the example below:
class human
{
protected:
int age;
public:
human(int a){age=a;}
void f(){cout<<"\n the age of human ="<<age;}
};
and the class below is derived from above class:
class student: public human
{
private:
int num;
public:
student(int b, int c):human(b){num=c;}
void g(){cout<<"\n the student with age "<<age<<" has " <<num;}
};
now I want to use these classes in the code below:
int main()
{
human h1(10);
student s1(11,4);
human* p=&h1;
p->f();
p=&s1;
p->g();
}
but the compiler gives me error on the p->g().
what is the problem?
Your base class pointer still points to a base class object human* p=&h1;. Try something like this:
#include <iostream>
class human
{
protected:
int age;
public:
human(int a){ age = a; }
void f(){ std::cout << "\n the age of human =" << age; }
virtual void g(){}
};
// class student code here...
int main()
{
human* p = new student(11, 4);
p->f();
p->g();
delete p;
return 0;
}
or instead use the s1 object and not the h1:
student s1(11, 4);
human* p = &s1;
The function g() is not part of the interface of the class human. p is a human*. If you upcast p to a student*, it will work.
The compiler doesn't know that your pointer is of student, it only sees the declaration as human. To fix this you need to cast it to a student pointer.
((student*)p)->g();
You can announce a virtual g in the Human.
class human {
public:
virtual void g() {}
... ...
};
In your example main() has two objects: human h1 and student s1.
int main()
{
human h1(10);
student s1(11,4);
human* p=&h1;
p->f();
p=&s1;
p->g();
}
Aside from the constructor, the declaration of the parent class human has only the function f() and the child class student, only adds the one function g().
The human pointer can look up only the function contained in it's class. Any information in the child's look up table is unknown to the parent because human was never told anything about the child class.
Passing the child object's reference &s1 to the parent pointer means that the parent can only look up the function it already knows. This is sometimes called object slicing. The child function g() has no place keeper in the parent's class. But, the child has both functions in it's look up table.
In other words, the child knows both itself and it's parent because it is declared class student: public human but the parent class knows only itself because it is merely declared "class human"
As Bauss says, it is possible to "upcast" the human pointer but I would not recommended that style. It will only confuse what type of pointer is being actually used.
This is the way I would rewrite main:
int main()
{
human h1(10);
human* p=&h1;
p->f();
/* prints " the age of human = 10" */
student s1(11,4);
student* q=&s1;
q->f();
/* prints " the age of human = 11" */
q->g();
/* prints " the student with age 10 has 4" */
}