I am a beginner and just can't figure out what am I doing wrong in this code. The result ends in a infinite loop (I think), that prints nothing. I intentionally left function speak() non-virtual and I know I'll only get Animal's data printed.
#include <iostream>
#include <string>
using namespace std;
class Animal
{
protected:
string m_name;
string m_speak;
public:
Animal(string name, string speak = "???"): m_name(name), m_speak(speak){}
string speak(){cout << m_name << " speaks " << m_speak;}
};
class Dog: public Animal
{
private:
string m_dspeak;
public:
Dog(string name, string speak = "Woof!"): Animal(name), m_dspeak(speak){}
string speak(){cout << m_name << " speaks " << m_dspeak;}
};
class Cat: public Animal
{
private:
string m_cspeak;
public:
Cat(string name, string speak = "Meow!"): Animal(name), m_cspeak(speak){}
string speak(){cout << m_name << " speaks " << m_cspeak;}
};
int main()
{
Cat Fred("Fred");
Dog Stuffy("Stuffy");
Animal *ptr = &Fred;
cout << ptr->speak() << endl;
Animal *ptr2 = &Stuffy;
cout << ptr2->speak() << endl;
}
Can someone help? I may did a very silly mistake here. Please tell me what's wrong?
In your code, you have made two major mistakes.
In the classes Animal, Dog and Cat you have three speak functions. But you declared them as string type functions. But the only output some text but does not return anything. You have to change them to void. Or you can return the text instead of outputing it.
In the main function you have written cout << ptr->speak() << endl; to output the text. But your speak function does not return any string to output. It outputs the text itself. So, you have to write ptr->speak(); to output the speech of the animal. You don't need cout there.
I have given two sample codes below. You can choose either of them. Both works just fine.
Sample #1: using void (no cout in main)
#include <iostream>
#include <string>
using namespace std;
class Animal
{
protected:
string m_name;
string m_speak;
public:
Animal(string name, string speak = "???"): m_name(name), m_speak(speak){}
void speak(){cout << m_name << " speaks " << m_speak;}
};
class Dog: public Animal
{
private:
string m_dspeak;
public:
Dog(string name, string speak = "Woof!"): Animal(name), m_dspeak(speak){}
void speak(){cout << m_name << " speaks " << m_dspeak;}
};
class Cat: public Animal
{
private:
string m_cspeak;
public:
Cat(string name, string speak = "Meow!"): Animal(name), m_cspeak(speak){}
void speak(){cout << m_name << " speaks " << m_cspeak;}
};
int main()
{
Cat Fred("Fred");
Dog Stuffy("Stuffy");
Animal *ptr = &Fred;
ptr->speak();
Animal *ptr2 = &Stuffy;
ptr2->speak();
}
Sample #2: using return in functions and cout in main
#include <iostream>
#include <string>
using namespace std;
class Animal
{
protected:
string m_name;
string m_speak;
public:
Animal(string name, string speak = "???"): m_name(name), m_speak(speak){}
string speak(){return m_name + " speaks " + m_speak;}
};
class Dog: public Animal
{
private:
string m_dspeak;
public:
Dog(string name, string speak = "Woof!"): Animal(name), m_dspeak(speak){}
string speak(){ return m_name + " " + m_speak;}
};
class Cat: public Animal
{
private:
string m_cspeak;
public:
Cat(string name, string speak = "Meow!"): Animal(name), m_cspeak(speak){}
string speak(){ return m_name + " speaks " + m_cspeak;}
};
int main()
{
Cat Fred("Fred");
Dog Stuffy("Stuffy");
Animal *ptr = &Fred;
cout << ptr->speak() << endl;
Animal *ptr2 = &Stuffy;
cout << ptr2->speak() << endl;
}
Change your two implementations of speak() to be something like this:
string speak(){ return m_name + " speaks " + m_speak; }
Currently, your speak methods don't have a return statement, so the return value is undefined, which could cause weird problems.
I am sorry I misunderstood your question. I edited the answer.
You do not need to cout in the function. You would do that in main.
#include <iostream>
#include <string>
using namespace std;
class Animal
{
protected:
string m_name;
string m_speak;
public:
Animal(string name, string speak = "???"): m_name(name), m_speak(speak){}
string speak(){return m_name + " speaks " + m_speak;}
};
class Dog: public Animal
{
private:
string m_dspeak;
public:
Dog(string name, string speak = "Woof!"): Animal(name), m_dspeak(speak){}
string speak(){ return m_name + " " + m_speak;}
};
class Cat: public Animal
{
private:
string m_cspeak;
public:
Cat(string name, string speak = "Meow!"): Animal(name), m_cspeak(speak){}
string speak(){ return m_name + " speaks " + m_cspeak;}
};
int main()
{
Cat Fred("Fred");
Dog Stuffy("Stuffy");
Animal *ptr = &Fred;
cout << ptr->speak() << endl;
Animal *ptr2 = &Stuffy;
cout << ptr2->speak() << endl;
}
Related
I've just learnt about inheritance and started using casting. While I was messing around trying to get to know the topic I found myself facing this problem which I couldn't explain. Here's the code:
#include <iostream>
#include <string>
using namespace std;
__interface AbstractClass {
void Eat()const;
void Sleep()const;
void Work()const;
string Info();
};
class Employee : public AbstractClass {
private:
string lastName;
int age, salary;
static int EmpCounter;
protected:
string name;
public:
Employee(string n = "Avto", string ln = "Chachandize", int a = 18, int s = 3000)
: name(n), lastName(ln), age(a), salary(s) {
EmpCounter++;
}
virtual ~Employee() {
EmpCounter--;
}
static int getEmpCounter() {
return EmpCounter;
}
void Eat()const override {
cout << name << " Is eating" << endl;
}
void Sleep()const override {
cout << name << " Is sleeping" << endl;
}
void Work()const override {
cout << name << " Is doing his/her stuff" << endl;
}
string Info() override {
string a = to_string(age);
string s = to_string(salary);
return name + ' ' + lastName + ' ' + a + ' ' + s + ' ';
}
};
int Employee::EmpCounter = 0;
class Developer : public Employee {
string language;
public:
Developer(string n = "Avto", string ln = "Chachandize", int a = 18, int s = 3000, string l = "C++") :
Employee(n, ln, a, s), language(l) {}
~Developer()override = default;
void Work()const override {
cout << name << " Is writing code in " << language << endl;
}
string Info() override {
Employee* emp = static_cast<Employee*>(this);
//Employee emp = static_cast<Employee>(*this);
return emp->Info() + ' ' + language;
}
};
int main() {
Developer dev;
cout << dev.Info() << endl;
}
I was trying to upcast Developer to Employee and then get his info. However static cast with pointers gives me error .
Strangely, second one which is commented doesn't. I don't know what is the reason of that. I also tried it with reference and there's also error. Same thing happened while using dynamic cast.
string Info() override {
Employee* emp = static_cast<Employee*>(this);
//Employee emp = static_cast<Employee>(*this);
return emp->Info() + ' ' + language;
}
So my question is, is that supposed to be an error or not?
As it was suggested you do not need to use casts when you want to get pointer to object to base class from the pointer to object to child class.
But it seems you want to call "Info" method of base class ("Employee") inside the body of "Info" method of the child class ("Developer"). It can be done in the following way:
Employee::Info();
for example in your case:
string Info() override {
return Employee::Info() + ' ' + language;
}
I have a homework task with a given main.cpp code which is not allowed to be changed. According to that main.cpp and simple input and output(which is down below) example I must to finish the program.
My tries are: I'm trying to create 4 classes, class Person; class Worker; class Student; class InService; in my main function through instantiating an object of InService class I pass 4 parameters (name, sex, studentNo, workerNo); and with help of pointer of type of Base class, have the desired output. The error it shows is:
[Error] no unique final overrider for 'virtual std::string Person::getName()' in 'InService'
[Error] no unique final overrider for 'virtual int Person::getSex()' in 'InService'
I've tried to use virtual inheritance for that, but I can't really figure out how to solve this problem. I did some research on virtual inheritance, and referenced to other experts answers, but still getting confused with whole OOP stuff.
//Inservice.h
#include<string>
using namespace std;
class Person{
public:
Person();
~Person();
string name;
int sex;
virtual string getName() = 0;
virtual int getSex() = 0;
};
///////////////////////////////////////////////////
class Student:virtual public Person{
public:
Student();
~Student();
string sno;
virtual string getName() {
return name;
}
virtual int getSex(){
return sex;
}
string getSno(){
return sno;
}
};
//////////////////////////////////////////////////
class Worker:virtual public Person{
public:
Worker();
~Worker();
string wno;
virtual std::string getName(){
return name;
}
virtual int getSex(){
return sex;
}
string getWno(){
return wno;
}
};
///////////////////////////////////////////////////////
class InService: public Student, public Worker{
public:
InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
};
///////////////////////////////////////////////////////
//main.cpp
#include <iostream>
#include "inservice.h"
using namespace std;
int main() {
string name, sno, wno;
int sex;
cin >> name;
cin >> sex;
cin >> sno;
cin >> wno;
InService is(name, sex, sno, wno);
Person* p = &is;
Student* s = &is;
Worker* w = &is;
cout << p->getName() << endl;
cout << p->getSex() << endl;
cout << s->getName() << endl;
cout << s->getSex() << endl;
cout << s->getSno() << endl;
cout << w->getName() << endl;
cout << w->getSex() << endl;
cout << w->getWno() << endl;
return 0;
}
Suppose my input is:
Jack
1 //1-for male; 0 -for female
12345678 //studentNo
87654321 //workerNo
I expect the output to be:
Jack
1
12345678
Jack
1
87654321
InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
There's a typo there, Person::sex - _sex; should be Person::sex = _sex;
Also you can remove name and sex virtual function and have it just a standard function in Person, since it's exactly the same for all classes that derive from it. That will remove the ambiguity of which getName and getSex function that InService class virtual table needs to point to.
searched all over, Couldn't find answer I'm looking for w.r.t. unique_ptr. It's a problem I came across, couldn't solve it with unique_ptr, but I could do with traditional way.
I'm stuck with having array of pointers to abstract_base_class pointing to inherited class
Sorry posting whole code
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <memory>
using namespace std;
// Base is an abstract base class.
class Base {
private:
string myName; // Name of this person
public:
Base(string name) : myName(name) {}
// A pure virtual function with a function body
virtual void hello() const {
cout << "Hello, my name is " << myName
<< ". ";
}
};
class ServiceAgent : public Base {
public:
ServiceAgent(string name) : Base(name) {}
void hello() const {
Base::hello();
cout << "I'm a customer service representative. How may I help you?"
<< endl;
cout << "-----\n";
}
};
class Student : public Base {
public:
enum category { FRESHMAN, SOPHOMORE, JUNIOR, SENIOR };
category personType;
Student(string name, category pType) : Base(name) {
personType = pType;
}
void hello() const {
string tmp = enumToString(personType);
Base::hello();
cout << tmp << endl;
cout << "-----\n";
}
string enumToString (category c) const
{
string s;
switch (c) {
case FRESHMAN:
s = "I'm a Freshman";
break;
case SOPHOMORE:
s = "I'm a Sophomore";
break;
case JUNIOR:
s = "I'm a Junior";
break;
case SENIOR:
s = "I'm a Senior";
break;
default:
s = "none";
break;
}
return s;
}
};
class CSStudent : public Student {
public:
CSStudent(string name, Student::category type) : Student(name, type) {}
void hello() const {
Base::hello();
cout << "I'm a computer science major.\n";
cout << "-----\n";
}
};
class BUSStudent : public Student {
public :
BUSStudent(string name, Student::category type) : Student(name, type) {}
void hello() {
Base::hello();
cout << "I'm a business major.\n";
cout << "-----\n";
}
};
int main() {
ServiceAgent *agentJack = new ServiceAgent("Jacqueline");
Student *studentJack = new Student("Jackson", Student::FRESHMAN);
CSStudent *studentCSS = new CSStudent("Jack", Student::SOPHOMORE);
BUSStudent *studentBus1 = new BUSStudent("Jacky", Student::JUNIOR);
BUSStudent *studentBus2 = new BUSStudent("Joyce", Student::SENIOR);
Base *arr[] = { agentJack, studentJack, studentCSS, studentBus1, studentBus2};
for (Base *var : arr)
{
var->hello();
}
unique_ptr<ServiceAgent> u_agentJack(new ServiceAgent("Jacqueline"));
unique_ptr<Student> u_studentJack(new Student("Jackson", Student::FRESHMAN));
unique_ptr<CSStudent> u_studentCSS(new CSStudent("Jack", Student::SOPHOMORE));
unique_ptr<BUSStudent> u_studentBus1(new BUSStudent("Jacky", Student::JUNIOR));
unique_ptr<BUSStudent> u_studentBus2(new BUSStudent("Joyce", Student::SENIOR));
//unique_ptr<Base*> ptr ; //(new Base*);//{ u_agentJack, u_studentJack, u_studentCSS, u_studentBus1, u_studentBus2 };
//ptr = static_cast<unique_ptr<Base*>>u_agentJack;
return 0;
}
I tried these, doesn't work.
unique_ptr<Base*> ptr (new (Base*[5] { u_agentJack, u_studentJack, u_studentCSS, u_studentBus1, u_studentBus2 });
tried with single entry
//ptr = static_cast<unique_ptr<Base*>>u_agentJack;
Change std::unique_ptr<Base*> to std::unique_ptr<Base>, and add a virtual destructor to Base. Then you can declare an array of unique_ptr<Base> objects the same way you declare an array of Base* pointers, and std::move() your existing std::unique_ptr objects into the array.
Try this:
#include <iostream>
#include <string>
#include <memory>
using namespace std;
// Base is an abstract base class.
class Base {
private:
string myName; // Name of this person
public:
Base(string name) : myName(name) {}
virtual ~Base() {}
// A pure virtual function with a function body
virtual void hello() const {
cout << "Hello, my name is " << myName << ".";
}
};
class ServiceAgent : public Base {
public:
ServiceAgent(string name) : Base(name) {}
void hello() const override {
Base::hello();
cout << " I'm a customer service representative. How may I help you?" << endl;
}
};
class Student : public Base {
public:
enum category { FRESHMAN, SOPHOMORE, JUNIOR, SENIOR };
category personType;
Student(string name, category pType) : Base(name), personType(pType) {}
void hello() const override {
Base::hello();
cout << " " << enumToString(personType) << endl;
}
string enumToString (category c) const
{
switch (c) {
case FRESHMAN:
return "I'm a Freshman";
case SOPHOMORE:
return "I'm a Sophomore";
case JUNIOR:
return "I'm a Junior";
case SENIOR:
return "I'm a Senior";
}
return "";
}
};
class CSStudent : public Student {
public:
CSStudent(string name, Student::category type) : Student(name, type) {}
void hello() const override {
Student::hello();
cout << "I'm a computer science major." << endl;
}
};
class BUSStudent : public Student {
public :
BUSStudent(string name, Student::category type) : Student(name, type) {}
void hello() const override {
Student::hello();
cout << "I'm a business major." << endl;
}
};
int main() {
std::unique_ptr<ServiceAgent> agentJack(new ServiceAgent("Jacqueline"));
std::unique_ptr<Student> studentJack(new Student("Jackson", Student::FRESHMAN));
std::unique_ptr<CSStudent> studentCSS(new CSStudent("Jack", Student::SOPHOMORE));
std::unique_ptr<BUSStudent> studentBus1(new BUSStudent("Jacky", Student::JUNIOR));
std::unique_ptr<BUSStudent> studentBus2(new BUSStudent("Joyce", Student::SENIOR));
std::unique_ptr<Base> arr[] = { std::move(agentJack), std::move(studentJack), std::move(studentCSS), std::move(studentBus1), std::move(studentBus2) };
for (auto &var : arr)
{
var->hello();
cout << "-----" << endl;
}
return 0;
}
Live Demo
I am working on an assignment using sub classes demonstrating polymorphism. This program requires a name to be given for each of the new objects. I am only supposed to have string getName(){return name;} (this is located in the base class). There is also a constructor in each of the classes class(string){}. In the main function I want to set the name for each of the objects. Any advice is much appreciated in how I should do so!
h file:
#ifndef DUCK_H
#define DUCK_H
#include <string>
using namespace std;
class Duck
{
private:
string name;
public:
Duck(){}
Duck(string){}
string getName() { return name; };
virtual string quack() {return "Which"; }
virtual string fly() { return "How?"; }
};
class RubberDuck : public Duck
{
public:
RubberDuck(){}
RubberDuck(string) {}
string quack() { return "Squeak"; }
string fly() { return "Fly with bounce"; }
};
class MallardDuck : public Duck
{
public:
MallardDuck(){}
MallardDuck(string) {}
string quack() { return "Quack"; }
string fly() { return "Fly with wings"; }
};
class RocketDuck : public Duck
{
public:
RocketDuck(){}
RocketDuck(string) {}
string quack() { return "Zoom"; }
string fly() { return "Fly with rockets"; }
};
#endif // !1
cpp file:
#include <iostream>
#include "Duck.h"
using namespace std;
//void display(Duck *d);
int main()
{
Duck d1;
MallardDuck md;
RubberDuck rbd;
RocketDuck rd;
//for main duck
//Duck duck("Donald");
//cout << duck.getName();
cout << d1.quack() <<"\n";
cout << d1.fly() <<"\n";
cout << "\n";
//for rubber duck
RubberDuck rbdname("Rubby");
cout << rbd.quack() << "\n";
cout << rbd.fly() << "\n";
cout << "\n";
//for mallard duck
MallardDuck mdname("Mally");
cout << md.quack() << "\n";
cout << md.fly() << "\n";
cout << "\n";
// for rocket duck
RocketDuck rdname("Rocky");
cout << rd.quack() << "\n";
cout << rd.fly() << "\n";
cout << "\n";
//polymorphism
Duck *d2 = new MallardDuck();
cout << d2->getName() << "\n";
cout << d2->quack() << "\n";
cout << d2->fly() << "\n";
cout << "\n";
return 0;
}
/*void display(Duck d)
{
cout << d.quack();
}
*/
Are you asking how to call the constructor you've defined? You would do that like
Duck duck("Drake Mallard");
With this code:
Duck(){}
Duck(string){}
You don't initialize your member name, whether you call the default constructor or the string one.
You have to use the input parameter like I showed you:
Duck(string const & input_name) : name(input_name) {}
^^^^^^^^^^^^^^^^
The underlined part initializes your member name to the value "Drake Mallard" when you do:
Duck duck("Drake Mallard");
Then, you will have duck.getName() returning "Drake Mallard".
And you have to apply the same principle in your derived classes, to call this very same base constructor:
class RubberDuck : public Duck
{
public:
RubberDuck() : Duck("RubberDuck") {}
RubberDuck(string const & input_name) : Duck(input_name) {}
Then
RubberDuck rubber; // name = "RubberDuck"
RubberDuck rubber("Ruber"); // name = "Rubber"
But also:
RubberDuck * rubber = new RubberDuck(); // name = "RubberDuck"
RubberDuck * rubber = new RubberDuck("Ruber"); // name = "Rubber"
If you ask, the front part Duck:: in my comment considered you where implementing your constructor outside of class Duck { ... };.
You should avoid using namespace, especially within headers.
My task was to create an object in class, initialize it and output(using pointer to class). This code compiles perfectly, but the output doesn't appear. I would really appreciate any help, thank you in advance!
#include <iostream>
#include <string>
using namespace std;
class family
{
public:
void setWife(string w)
{w = wife;};
string getWife()
{return wife;};
void setHusband(string h)
{husband = h;};
string getHusband()
{return husband;};
void setSon(string s)
{s = son;};
string getSon()
{return son;};
void setDaughter1(string d1)
{d1 = daughter1;};
string getDaughter1()
{return daughter1;};
void setDaughter2(string d2)
{daughter2 = d2;};
string getDaughter2()
{return daughter2;};
double* getPointer()
{return &pointer;};
void initialize()
{
setWife("Shirley Collin");
setHusband("Donald Collin");
setSon("Collin Collin");
setDaughter1("Harriet Collin");
setDaughter2("Hillary Collin");
}
friend void output(family* Collin);
private:
string wife;
string husband;
string son;
string daughter1;
string daughter2;
double pointer;
};
void output(family* Collin)
{cout << "Husband is " <<Collin->getHusband()<< endl;
cout << "wife is " << Collin ->getWife() << endl;
cout << "son is " << Collin->getSon() << endl;
cout << "daughter1 is " << Collin->getDaughter1() << endl;
cout << "daughter2 is " << Collin->getDaughter2()<< endl;
};
int main()
{family Collin;
Collin.initialize();
family *pointer = new family;
output (pointer);
cin.ignore();
}
family Collin;
Collin.initialize();
This constructs an instance of the family class, and initializes it with the values defined in the initialize() method.
family *pointer = new family;
output (pointer);
This constructs a second instance of the family class, does not initialize it in any way, and calls the output() method, to display the contents of the completely uninitialized second instance of this family class.
This is why this program produces no useful output.
You probably want to replace these four lines with:
family *pointer=new family;
pointer->initialize();
output(pointer);