Base class's functions aren't being overridden in C++ - c++

[The code below is runnable so feel free to run it to see what I am talking about]
I am following along with a tutorial from a book that is Java-based. The code below is essentially a bunch of classes that can be used to accurately get the description and price of a beverage ordered (no matter how many additional condiments are added on to the base Beverage). The issue is the getDescription() and cost() functions in the Beverage class are not being overridden by the CondimentDecorator class, or any of the various condiment classes (Mocha, Milk, Whip, etc.).
When I run it, "Unknown Beverage" prints out as the description.
How can I figure out where the inheritance bug is at?
#include <iostream>
#include <string>
using namespace std;
class Beverage {
string description = "Unknown Description";
public:
string getDescription(){
return description;
}
int cost(); // just declare it - don't do anything
};
class HouseBlend : public Beverage {
string description = "House Blend";
string getDescription(){
return description;
}
int count(){
return .89;
}
};
class DarkRoast : public Beverage {
string description = "Dark Roast";
string getDescription(){
return description;
}
int count(){
return .99;
}
};
class Decaf : public Beverage {
string description = "Decaf";
string getDescription(){
return description;
}
int count(){
return 1.05;
}
};
class Espresso : public Beverage {
string description = "Espresso";
string getDescription(){
return description;
}
int count(){
return 1.99;
}
};
class CondimentDecorator : public Beverage {
string getDescription();
};
class Soy : public CondimentDecorator {
Beverage *beverage;
public:
Soy(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Soy ";
}
int cost(){
return beverage->cost() + .15;
}
};
class Milk : public CondimentDecorator{
Beverage *beverage;
public:
Milk(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Milk ";
}
int cost(){
return beverage->cost() + .10;
}
};
class Mocha : public CondimentDecorator{
Beverage *beverage;
public:
Mocha(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Mocha ";
}
int cost(){
return beverage->cost() + .20;
}
};
class Whip : public CondimentDecorator{
Beverage *beverage;
public:
Whip(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Whip ";
}
int count(){
return beverage->cost() + .10;
}
};
//class StarbuzzCoffeeRun {
int main(){
Beverage *beverage = new Espresso;
cout << beverage->getDescription(); // << "$" << beverage->cost() << endl ;
Beverage *beverage2 = new DarkRoast;
beverage2 = new Mocha(beverage2);
cout << beverage2->getDescription();
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
cout << beverage2->getDescription(); // << "$" << beverage2->cost() << endl ;
Beverage *beverage3 = new HouseBlend;
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
cout << beverage3->getDescription(); // << "$" << beverage3->cost() << endl ;
return 0;
}

Couple of things wrong here.
The biggest one (causing the problem you're seeing) is that by doing something like this:
class HouseBlend : public Beverage {
string description = "House Blend";
// ...
};
What you're actually doing here is declaring a new member description, not setting Beverage's description.
To actually set Beverage's variable description, you will need to set it in a constructor or something:
class HouseBlend : public Beverage {
public:
HouseBlend () {
description = "House Blend";
}
};
Of course, if you want to access a parent's variable inside the child, it will have to be public or protected:
class Beverage {
protected:
string description = "Unknown Description";
public:
string getDescription(){
return description;
}
int cost(); // just declare it - don't do anything
};
Of course, you could set it in a setter too, but you you get the idea.
The other thing wrong here is with your count() function:
int cost(); // just declare it - don't do anything
There are 2 things wrong with this:
It needs to be virtual. If it's not, it will just end calling the base function and not the overloaded one when you create a pointer to it.
virtual int cost(); // so the compiler knows it will get overloaded at runtime
It needs to have an implementation. Even if the function does nothing, it still needs to have an "implementation" or else the compiler will complain.
virtual int cost() {return 0;} // Return some value that we know shouldn't exist
If you have a virtual function, you have the option of a pure virtual function which allows you to have no implementation, but override it in the child class:
virtual int cost() = 0; // This function has no implementation, but derived classes will give it one.
Note that this makes Beverage into a abstract class, and that comes with some restrictions for how you can use it. However, you seem to use it like an abstract class, so I'm guessing that this is what you were expecting anyway.
Edit
So, after I hit "post," I realized that technically I didn't answer your question which seems to be why getDescription() doesn't get overridden. The answer is similar to cost(), in that it needs to be virtual as well:
class Beverage {
string description = "Unknown Description";
public:
virtual string getDescription(){
return description;
}
virtual int cost() = 0;
};
This will technically allow getDescription() to get overridden when you use it in a pointer context. However, this isn't the best solution. It is probably better in the long run to make description protected instead.
Otherwise you're making a bunch of extra description variables you don't need. That will ultimately waste memory. And it makes your design clunkier. So just use protected instead.

Related

Initializing data members of base class using the constructor of privately derived class

I am new to c++ programming,I am trying to execute the following code but it
shows the error
no matching function for call to ‘Flower::Flower()’ Rose(string n =
"No flower", string c = "Red") : color(c) {}
even though i have given parametric constructor in my class Flower still it says no matching function call.
#include <iostream>
#include <string>
using namespace std;
class Flower
{
public:
string name;
Flower (string n):name (n)
{
}
void getFlowerName ()
{
cout << name << " " << "is" << " ";
}
};
class Rose:private Flower
{ // Inherit Flower as private
public:
string color;
/* Initialize name and color data members */
Rose (string n = "No flower", string c = "Red"):color (c)
{
}
void getFlowerName (Rose & r)
{
cout << r.color << endl;
}
// using Flower::getFlowerName ;// Allow call to getFlowerName() method in the base class
};
class Rose:private Flower
{ // Inherit Flower as private
public:
string color;
/* Initialize name and color data members */
Rose (string n = "No flower", string c = "Red"):color (c)
{
}
void getFlowerName (Rose & r)
{
cout << r.color << endl;
}
using Flower::getFlowerName; // Allow call to getFlowerName() method in
the base class
};
Derived classes should call base classes:
class Rose : private Flower
{
public:
std::string color;
Rose (const std::string& n = "No flower",
const std::string& c = "Red") : Flower(n), color(c)
{
}
// ...
};
As currently you call implicitly the default Flower's constructor, but it is not existent.
Create Flower::Flower() default constructor.
Flower(){ name = NULL; }

Why is the pointer in this nested class missing?

Question in short:
class B has a ptr to class C, which has a class D having a ptr to class B
assign class B to an array in class A by copying, expecting to see to ptr points to new instance in the array not original instance, but failed.
I am already able to do some workaround, but I want to know why my original approach fails.
More detailed explainations are as follows, and the code to reproduce the problem is posted as well
Anyone who is able to explain what is going on is appreciated.
There are 6 classes:
class CastInfo //contains a Character*
class Skill //abstract class, contains CastInfo
class Movvement : public Skill
class Move1 : public Movement
class Character //contains a Movement*, which will be Move1* in practice
class Squad //contains an array of Character
with the following relationships:
Character* in CastInfo should point to the Character who owns the Skill which
is the owner of CastInfo
when assigning the Skill to Character, the Character* in CastInfo points to that Character
the Character in Squad's array should be copied, so there will be 2 instances and the Character* in CastInfo should also point to Character in Squad's array not original instance
The expecting result is:
move1 != ch1.move1 != squad.ch[0].move1 (this is already satisfied)
ch1.move1->cast_info.caster == &ch1 != squad.ch[0].move1->caster_info.caster (this is the problem)
There are 2 cases (tried) of the output:
In the Squad's constructor,:
if using
characters_[i] = characters[i];
the character is correctly copied, but the skill is at same address
move1: 00000270E6093500
ch1: 000000BC6DCFF378
ch1.move1: 00000270E6093E60
ch1.move1->cast_info.caster: 000000BC6DCFF378
squad.ch[0]: 000000BC6DCFF3E0
squad.ch[0].move1: 00000270E6093E60
squad.ch[0].move1->cast_info.caster: 000000BC6DCFF378
if using
characters_[i] = Character(characters[i]);
the character is correctly copied, but the skill is missing (pointing to some weird location)
move1: 00000230FDCEF080
ch1: 00000058A11DF548
ch1.move1: 00000230FDCEF260
ch1.move1->cast_info.caster: 00000058A11DF548
squad.ch[0]: 00000058A11DF5B0
squad.ch[0].move1: 00000230FDCEF0E0
squad.ch[0].move1->cast_info.caster: 00000058A11DF378
In the first case, I guess it is probably because I did not overload operator=, so only address is copied. I tried to overload it but it caused more problem. (Such as when using Builder.Build() )
In the second case, I expect it first call copy constructor, which triggers SetMove1(), which calls SetCaster(). move1 is cloned as shown, but I cannot understand why caster is not updated correctly. (Though is calls operator= after construnction, the address should remain the same.)
The following code should reproduce the problem:
motion.h
#pragma once
class Character;
struct CastInfo
{
Character* caster;
int coeff;
};
class Skill
{
public:
CastInfo cast_info;
Skill() {};
~Skill() {};
virtual void DoSomething() = 0;
};
class Movement : public Skill
{
public:
Movement();
~Movement();
virtual void DoSomething() { ; }
virtual Movement* Clone() const { return new Movement(*this); }
};
class Move1 : public Movement
{
public:
Move1() { cast_info.coeff = 123; }
void DoSomething() { ; }
virtual Move1* Clone() const { return new Move1(*this); }
};
class Move2 : public Movement
{
public:
void DoSomething() { ; }
};
motion.cpp:
#include "motion.h"
Movement::Movement() { }
Movement::~Movement() { }
test.h:
#pragma once
#include <string>
#include <vector>
#include "motion.h"
#define SQUAD_SIZE 6
extern Movement* null_movement;
class Character
{
public:
class Builder;
Character();
~Character();
Character(const Character& character);
Character& SetMove1(Movement* skill);
public:
int id_;
Movement* move1_ = null_movement;
Movement* move2_ = null_movement;
Character(int id) : id_(id) { ; }
void SetCaster();
};
class Character::Builder : public Character
{
public:
Builder& SetId(int i) { id_ = i; return *this; }
Character Build() { return Character(id_); }
};
class Squad
{
public:
class Builder;
Squad() { }
Squad(const Squad& squad);
~Squad() { }
public:
Character characters_[SQUAD_SIZE];
Squad(Character* characters);
};
class Squad::Builder :public Squad
{
public:
Builder& SetCharacter(const Character& character, const int position) { characters_[position] = character; return *this; }
Squad Build() { return Squad(characters_); }
};
test.cpp
#include <iostream>
#include "test.h"
Movement* null_movement = new Move2();
Character::Character() : id_(0) { }
Character::~Character() {}
Character::Character(const Character& character) {
id_ = character.id_;
SetMove1(character.move1_);
}
Character& Character::SetMove1(Movement* move1) {
if (!move1) return *this;
move1_ = move1->Clone();
SetCaster();
return *this;
}
void Character::SetCaster() {
if (move1_ != NULL) move1_->cast_info.caster = this;
}
Squad::Squad(const Squad& squad) {
*this = squad;
}
Squad::Squad(Character* characters) {
for (int i = 0; i < SQUAD_SIZE; i++) {
//characters_[i] = characters[i]; //character copied, skill same address
characters_[i] = Character(characters[i]); //character copied, skill missing
}
}
main.cpp
#include <iostream>
#include "test.h"
#include "motion.h"
int main() {
Move1* move1 = new Move1();
std::cout << "move1: " << move1 << std::endl;
Character ch1 = Character::Builder().SetId(1).Build();
Character ch2 = Character::Builder().SetId(2).Build();
ch1.SetMove1(move1);
std::cout << "ch1: " << &ch1 << std::endl;
std::cout << "ch1.move1: " << (ch1.move1_) << std::endl;
std::cout << "ch1.move1->cast_info.caster: " << (ch1.move1_->cast_info.caster) << std::endl;
Squad squad = Squad::Builder().SetCharacter(ch1, 0).SetCharacter(ch2, 1).Build();
std::cout << "squad.ch[0]: " << &(squad.characters_[0]) << std::endl;
std::cout << "squad.ch[0].move1: " << (squad.characters_[0].move1_) << std::endl;
std::cout << "squad.ch[0].move1->cast_info.caster: " << (squad.characters_[0].move1_->cast_info.caster) << std::endl;
system("PAUSE");
return 0;
}
As previously mentioned, I have a workaround to reach my goal:
By creating another method, which iterates through the array in Squad, and call each Character's SetCaster() method.
void Squad::SetCaster() {
for (int i = 0; i < SQUAD_SIZE; i++) {
characters_[i].SetCaster();
}
}
But I think this is dirty because every time after Builder::Builder(), SetCaster() must be called, which is unintuitive and error-prone.
I think I found the problem, as illustrated below:
The problem is in
Squad::Squad(Character* characters) {
for (int i = 0; i < SQUAD_SIZE; i++) {
//characters_[i] = characters[i]; //character copied, skill same address
characters_[i] = Character(characters[i]); //character copied, skill missing
}
}
As mentioned in question, using the commented line is just copying the values, which is incorrect.
What
characters_[i] = Character(characters[i]); //character copied, skill missing
does is as follows:
create a Character, by calling Character's constructer, this object is at address A. SetMove1() is called, SetCaster() is called. The pointer in cast_info is pointing at A correctly.
assign the object to characters_[i], whose address is at address B because the address of characters_ is assigned when Squad is created. As I did not overload Character::operator=, the pointer is still pointing to address A
Constructor done, Squad returned.
This is the reason
std::cout << "squad.ch[0].move1->cast_info.caster: " << (squad.characters_[0].move1_->cast_info.caster) << std::endl;
shows a third address (address A) which is neither &(character[0]) (address B) nor &ch1 (original character's address)
The solution is either to overload operator= or put my "workaround" (Squad::SetCaster()) in constructor right after the for loop.
Please correct me if there is anything wrong, or if there is any better solution.

Inheriting private members from base class to derived classes c++

I'm trying to inherit the name,skeletonType, and numLegs from my base class to my derived class.
I have a base class named Invertebrates and derived class named Spider. I want to be able to use the private variables with the derived class from my base class. I keep getting a compiling error on line 47 and it says expected primary-expression before ','.
I'm trying to get my output to look like this:
Spider:Brown Recluse, number of legs = 8, skeleton type = EXOSKELETON
Could someone help me out and point me in the right direction please. Here is what I put together so far.
// invertebrates.h
// invertebrate specifications
#ifndef _INVERTEBRATE_H_
#define _INVERTEBRATE_H_
#include <iostream>
using namespace std;
enum Skeleton_Type { NONE, HYDROSTATIC, EXOSKELETON };
class Invertebrate {
private:
string name;
Skeleton_Type skeletonType;
int numLegs;
protected:
void setSkeletonType(Skeleton_Type skeletonType);
void setNumLegs(int numLegs);
public:
Invertebrate();
Invertebrate(string name, Skeleton_Type skeletonType, int numLegs);
string getName();
Skeleton_Type getSkeletonType();
int getNumLegs();
virtual void print() = 0;
};
class Spider : public Invertebrate {
private:
const string NAME_PREFIX = "Spider: ";
public:
Spider();
Spider(string name);
virtual void print();
};
#endif // _INVERTEBRATE_H_
**********************************************************************
//invertebrates.cpp
#include "invertebrate.h"
void Invertebrate::setSkeletonType(Skeleton_Type skeletonType)
{
this->skeletonType = skeletonType;
}
void Invertebrate::setNumLegs(int numLegs)
{
this->numLegs = numLegs;
}
Invertebrate::Invertebrate()
{
name = "noName";
skeletonType = NONE;
numLegs = 0;
}
Invertebrate::Invertebrate(string name, Skeleton_Type skeletonType, int numLegs)
{
this->name = name;
this->skeletonType = skeletonType;
this->numLegs = numLegs;
}
string Invertebrate::getName()
{
return this->name;
}
Skeleton_Type Invertebrate::getSkeletonType()
{
return this->skeletonType;
}
int Invertebrate::getNumLegs()
{
return this->numLegs;
}
Spider::Spider(string name):Invertebrate(name,EXOSKELETON,8)
{
name = Invertebrate::getName();
}
void Spider::print()
{
string strSkType = "";
if(this->getSkeletonType() == 0)
strSkType= "none";
else if(this->getSkeletonType() == 1)
strSkType= "Hydrostatic";
else if(this->getSkeletonType() == 2)
strSkType= "exoskeleton";
cout << this->NAME_PREFIX + getName();
cout << ", number of legs = " << this->getNumLegs() << ", skeleton type = " << strSkType << endl;
}
int main()
{
Spider *sp = new Spider("Brown Recluse");
sp->print();
return 0;
}
OUTPUT:
Here are the issues in your code :-
In .h file -
const string NAME_PREFIX = "Spider: ";
is not a valid way to initialize cont members - const should be initialized through constructor initializer list (till C++11).
Correct way in .cpp
Spider::Spider(string name):NAME_PREFIX(name),Invertebrate(name,EXOSKELETON,8)
{
name = NAME_PREFIX + Invertebrate::getName();
}
In the same constructor you have written name&, which is wrong, just pass name.
Spider::Spider(string
name):NAME_PREFIX(name),Invertebrate(name,EXOSKELETON,8)
I think I finally discovered what your line 47 is:
Spider::Spider(string name):Invertebrate(name&,EXOSKELETON,8)
{
name = NAME_PREFIX + Invertebrate::getName();
}
This function has two problems:
What is that & in name&? That is not valid syntax!
You cannot access this->name directly, because it is private in the base class. Instead here you are modifying the local name argument, and that does nothing useful.
You could make the base name public or protected. Or you could add a setName() protected function.
But in my opinion this member is ok being private and read-only. The solution would be to specify the proper name at construction time:
Spider::Spider(string name)
:Invertebrate(NAME_PREFIX + name, EXOSKELETON, 8)
{
}

How do I make the loop for cataloging random variables in C++?

-Let me give some background first- My assignment is to take a given senario (my dog buddy sees a frog in the backyard and if he is hungry he eats it, if not he will play with it, if he's already eaten two he will let it go. If he sees a cat or a squirrel he will bark at it, if another dog he chases it, if a coyote he will cry for help, any other animal he will watch it). Then we are to have it count the number of animals in a given night and record it into another file along with Buddy's reactions to said animals. A person is to be able to enter a date into the recorded file and pull up the animals and interactions for said date.-
Here is the code as I have it currently:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class animal{
public:
animal();
~animal();
virtual string interactWithBuddy()//all derived classes use this
{
return "Buddy ";
}
};
animal::animal()
{
}
class frog: public animal
{
public:
string interactWithBuddy()
{
return "Buddy \n";
}
static int ID()
{
return 1;//ID assigned to frog for randomization purposes
}
};
class dog: public animal
{
public:
string interactWithBuddy()
{
return "Buddy chased the dog\n";
}
static int ID()
{
return 2;//ID assigned to dog for randomization purposes
}
};
class cat: public animal
{
public:
string interactWithBuddy()
{
return "Buddy barked at the cat \n";
}
static int ID()
{
return 3;//ID assigned to cat for randomization purposes
}
};
class coyote: public animal
{
public:
string interactWithBuddy()
{
return "Buddy cried for help when he seen the coyote \n";
}
static int ID()
{
return 4;//ID assigned to coyote for randomization purposes
}
};
class squirrel: public animal
{
public:
string interactWithBuddy()
{
return "Buddy barked at the squirrel \n";
}
static int ID()
{
return 5;//ID assigned to squirrel for randomization purposes
}
};
class otherAnimal: public animal
{
public:
string interactWithBuddy()
{
return "Buddy watched the animal \n";
}
static int ID()
{
return 6; //ID assigned to otherAnimal for randomization purposes
}
};
int main ()
{
srand(time(0)); //intializes the random seed
int number;
animal * a; // pointer to animal
std::cout << (rand() % 6 + 1) <<std::endl; //return random number between 1-6
// loop to assign the random number output a proper animal ID
if (number == frog::ID())
{
a = new frog;
a->interactWithBuddy();
}
else if (number == dog::ID())
{
a = new dog;
a->interactWithBuddy();
}
else if (number == cat::ID())
{
a = new cat;
a->interactWithBuddy();
}
else if (number == coyote::ID())
{
a = new coyote;
a->interactWithBuddy();
}
else if (number == squirrel::ID())
{
a = new squirrel;
a->interactWithBuddy();
}
else if (number == otherAnimal::ID())
{
a = new otherAnimal;
a->interactWithBuddy();
}
return 0;
}
Compiles without errors but when I code check it for the output I get an error that reads "Line 100: warning: 'number' is used uninitialized in this function"
virtual int ID() //allows declared value in subclass
{
return ("My ID number is\n");
}
The int means that the function returns an integer. But it actually returns a string (const char *). The compiler has no idea how to convert the const char * you returned into the int you were supposed to return.
As for the second question, you are returning a cstring from the function but you have declared the return type of the function as integer. Anything in between double quotes "" is considered as constant string. Change the return type of your function or either return an integer
For your first question, this may take a few tries.
First, suppose you just wanted to choose an animal randomly:
srand(time(0)); //initializes the random seed
int number = rand() % 6 + 1;
animal *a;
if(number == 1)
{
a = new frog;
}
if(number == 2)
{
a = new dog;
}
...
a->interactWithBuddy();
delete(a); // Don't forget to delete what you create with "new".
That works, but the ID numbers are "hard-coded" here, it doesn't use the ID() function you wrote. If you want to use ID(), you could have one of each animal and see which one matches number:
frog Kermit;
dog Ralph;
cat Felix;
coyote Loki;
squirrel Sparticus;
if(number == kermit.ID())
{
kermit.interactWithBuddy();
}
if(number == Ralph.ID())
{
Ralph.interactWithBuddy();
}
...
You have to have each animal beforehand, because you can't ask the animal for ID() until the animal exists. But there is a way to code ID() so that you can ask for the ID of a type of animal before you have one of that animal, by using "static":
class animal{
public:
animal();
~animal();
void interactWithBuddy();
};
class frog: public animal
{
public:
...
static int ID()
{
return 1;
}
};
...
int main()
{
...
if(number == frog::ID())
{
a = new frog;
}
...
}
This also solves your second problem because you no longer have the problematic OD() in animal.
Is that sufficient? There are other possibilities.
EDIT:
You forgot int number = rand() % 6 + 1;.
Your function is declared to return an integer - you are returning a null terminated string
Instead in the base class maybe return an error type ID like
virtual int ID()
{
return -1;
}

Adding two different Objects by overloading operator+ C++

I've been trying to figure out how to add a private member from Object A, to a private member from Object B.
Both Cat and Dog Class's inheriate from the base class Animal. I have a thrid class 'MyClass', that I want to inheriate the private members of the Cat and Dog class. So in MyClass, I have a friend function to overload the + operator. THe friend function is defined as follows:
MyClass operator+(const Dog &dObj, const Cat &cObj);
I want to access dObj.age and cObj.age within the above function, invoke by this statement in main:
mObj = dObj + cObj;
Here is the entire source for a complete reference into the class objects:
#include <iostream>
#include <vld.h>
using namespace std;
class Animal
{
public :
Animal() {};
virtual void eat() = 0 {};
virtual void walk() = 0 {};
};
class Dog : public Animal
{
public :
Dog(const char * name, const char * gender, int age);
Dog() : name(NULL), gender(NULL), age(0) {};
virtual ~Dog();
void eat();
void bark();
void walk();
private :
char * name;
char * gender;
int age;
};
class Cat : public Animal
{
public :
Cat(const char * name, const char * gender, int age);
Cat() : name(NULL), gender(NULL), age(0) {};
virtual ~Cat();
void eat();
void meow();
void walk();
private :
char * name;
char * gender;
int age;
};
class MyClass : private Cat, private Dog
{
public :
MyClass() : action(NULL) {};
void setInstance(Animal &newInstance);
void doSomething();
friend MyClass operator+(const Dog &dObj, const Cat &cObj);
private :
Animal * action;
};
Cat::Cat(const char * name, const char * gender, int age) :
name(new char[strlen(name)+1]), gender(new char[strlen(gender)+1]), age(age)
{
if (name)
{
size_t length = strlen(name) +1;
strcpy_s(this->name, length, name);
}
else name = NULL;
if (gender)
{
size_t length = strlen(gender) +1;
strcpy_s(this->gender, length, gender);
}
else gender = NULL;
if (age)
{
this->age = age;
}
}
Cat::~Cat()
{
delete name;
delete gender;
age = 0;
}
void Cat::walk()
{
cout << name << " is walking now.. " << endl;
}
void Cat::eat()
{
cout << name << " is eating now.. " << endl;
}
void Cat::meow()
{
cout << name << " says meow.. " << endl;
}
Dog::Dog(const char * name, const char * gender, int age) :
name(new char[strlen(name)+1]), gender(new char[strlen(gender)+1]), age(age)
{
if (name)
{
size_t length = strlen(name) +1;
strcpy_s(this->name, length, name);
}
else name = NULL;
if (gender)
{
size_t length = strlen(gender) +1;
strcpy_s(this->gender, length, gender);
}
else gender = NULL;
if (age)
{
this->age = age;
}
}
Dog::~Dog()
{
delete name;
delete gender;
age = 0;
}
void Dog::eat()
{
cout << name << " is eating now.. " << endl;
}
void Dog::bark()
{
cout << name << " says woof.. " << endl;
}
void Dog::walk()
{
cout << name << " is walking now.." << endl;
}
void MyClass::setInstance(Animal &newInstance)
{
action = &newInstance;
}
void MyClass::doSomething()
{
action->walk();
action->eat();
}
MyClass operator+(const Dog &dObj, const Cat &cObj)
{
MyClass A;
//dObj.age;
//cObj.age;
return A;
}
int main()
{
MyClass mObj;
Dog dObj("B", "Male", 4);
Cat cObj("C", "Female", 5);
mObj.setInstance(dObj); // set the instance specific to the object.
mObj.doSomething(); // something happens based on which object is passed in
dObj.bark();
mObj.setInstance(cObj);
mObj.doSomething();
cObj.meow();
mObj = dObj + cObj;
return 0;
}
If you want to access a private member of Dog, then your operator has to be a friend of Dog, not just a friend of some derived class of Dog.
If you add friend MyClass operator+(const Dog &dObj, const Cat &cObj); to the definition of class Cat and class Dog, then the function will have access to dObj.age and cObj.age.
Alternatively, you could add friend MyClass; to the definitions of class Cat and class Dog, but then all of MyClass's functions have access to all of Cat and Dog's internals.
Alternatively alternatively, you could make age protected rather than private.