C++ Inheritance & Polymorphism: Early vs. Late Binding with Sale & DiscountSale Classes - , Study notes of Data Structures and Algorithms

An example of c++ inheritance using the sale and discountsale classes. It explains the concept of early binding and how an object is cast back to its base class during compile time. The document also discusses the use of virtual functions for late binding and how it allows an object to use its own methods.

Typology: Study notes

Pre 2010

Uploaded on 08/16/2009

koofers-user-6zr
koofers-user-6zr 🇺🇸

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CSCI 3110
Inheritance (2)
An example of early binding
class Sale
{
public:
Sale();
Sale(double thePrice);
double GetPrice() const;
void SetPrice(double newPrice);
double Bill () const;
double Savings (const Sale & other) const;
protected:
double price;
};
Sale::Sale() : price (0){}
Sale :: Sale(double thePrice)
{ price = thePrice;
}
double Sale::Bill()
{ return price;
}
double Sale::GetPrice{} const
{ return price;
}
void Sale::SetPrice(double newPrice)
{ price = newPrice;
}
double Sale::Savings(const Sale & other) const
{ return (Bill() – other.Bill());
}
DiscountSale Class
class DiscountSale : public Sale
{
public:
DiscountSale();
DiscountSale(double thePrice, double
theDiscount);
double GetDiscount() const;
void GetDiscount(double
newDiscount);
double Bill() const;
private:
double discount;
};
DiscountSale::DiscountSale() : Sale(0), discount
(0)
{}
DiscountSale::DiscountSale(double thePrice,
double theDiscount):Sale(thePrice),
discount(theDiscount){}
double DiscountSale::GetDiscount() const
{ return discount;
}
void DiscountSale::SetDiscount(double
newDiscount)
{ discount = newDiscount;
}
double DiscountSale::Bill() const
{ double fraction = discount / 100;
return (1-fraction)*getPrice();
}
client program:
bool operator < (const Sale& first, const Sale &
second);
int main()
{ Sale simple(10.00);
DiscountSale disc(11.00, 10);
if (disc < simple)
{
cout << “Discounted item is
cheaper”;
cout << “Saving is $” <<
simple.saving(discount) << endl;
}
else
cout << “Discounted item is not
cheaper.”
}
bool operator < (const Sale& first, const Sale&
second)
{
return (first.bill() < second.bill())
}
pf3
pf4
pf5

Partial preview of the text

Download C++ Inheritance & Polymorphism: Early vs. Late Binding with Sale & DiscountSale Classes - and more Study notes Data Structures and Algorithms in PDF only on Docsity!

CSCI 3110

Inheritance (2)

An example of early binding

class Sale { public: Sale(); Sale(double thePrice); double GetPrice() const; void SetPrice(double newPrice); double Bill () const; double Savings (const Sale & other) const; protected: double price; };

Sale::Sale() : price (0){}

Sale :: Sale(double thePrice) { price = thePrice; }

double Sale::Bill() { return price; }

double Sale::GetPrice{} const { return price; }

void Sale::SetPrice(double newPrice) { price = newPrice; }

double Sale::Savings(const Sale & other) const { return (Bill() – other.Bill()); }

DiscountSale Class

class DiscountSale : public Sale { public: DiscountSale(); DiscountSale(double thePrice, double theDiscount);

double GetDiscount() const; void GetDiscount(double newDiscount); double Bill() const; private: double discount;

DiscountSale::DiscountSale() : Sale(0), discount (0) {}

DiscountSale::DiscountSale(double thePrice, double theDiscount):Sale(thePrice), discount(theDiscount){}

double DiscountSale::GetDiscount() const { return discount; }

void DiscountSale::SetDiscount(double newDiscount) { discount = newDiscount; }

double DiscountSale::Bill() const { double fraction = discount / 100; return (1-fraction)*getPrice(); }

client program:

bool operator < (const Sale& first, const Sale & second);

int main() { Sale simple(10.00); DiscountSale disc(11.00, 10);

if (disc < simple) { cout << “Discounted item is cheaper”; cout << “Saving is $” << simple.saving(discount) << endl; } else cout << “Discounted item is not cheaper.” }

bool operator < (const Sale & first, const Sale & second) { return (first.bill() < second.bill()) }

For operator < : “disc” which is an object of DiscountedSale class, is cast back to “Sale”

class during compile time – early binding (binding done at compile time )

As a result, the bill method associated with “first” is the “bill” method defined for Sale

class, not the bill method for DiscountSale class.

How to make an object always use its own methods, e.g., not being bound by methods

defined in base classes?

Answer: virtual functions

If a method is defined to be virtual, it is to tell the compiler, “ I do not know how this

function is implemented. Wait until it is used in a program, and then get the

implementation from the object instance” -- wait until run time to determine the

implementation of a function – late binding ( examples including overloaded

function, function passed as parameter…)

Change the above program to :

class Sale { public: Sale(); Sale(double thePrice); double GetPrice() const; void SetPrice(double newPrice); virtual double Bill () const; // Í this is the only change necessary, /* (a) if a method is defined to be virtual, then all new definitions of the function in the derived class will automatically be virtual (b) virtual modifier is not necessary in the implementation file. */ double Savings (const Sale & other) const; private: double price; };

/* output: Discounted item is cheaper Savings is $0. */

#ifndef MAM_H

#define MAM_H

class mammal

public:

mammal();

mammal (int W);

~mammal();

int ReturnWeight();

int ReturnHeight();

virtual void Speak()const;

protected:

int Age;

int Weight;

int Height;

#endif

#include

#include "mam.h"

#include "dog.h"

using namespace std;

int main()

mammal Animal;

dog MyDog;

Animal.Speak();

MyDog.Speak();

mammal* mamptr=&Animal;

mammal* dogptr=&MyDog;

cout <<"Mammal's pointer ";

mamptr Æ Speak();

cout << endl;

cout <<"Dog's pointer ";

dogptr Æ Speak();

cout << endl;

return 0;

Additional rules:

• constructors can not be virtual

• destructor

a. can, and should be virtual, Î guarantees that future descendants of the

object can de-allocate themselves correctly.

b. If any function in a class is virtual, destructor should be virtual as well.

c. A class destructor must be defined when a class allocates dynamic memory.

• virtual function’s return type can not be overridden

• Virtual function table

having “virtual function” introduces overhead, e.g., more storage is needed. So,

C++ gives this flexibility to the programming to decide which functions should be

made virtual. If a function does not need to take advantage of being virtual, then

not making it virtual makes the program runs more memory efficient.

o Each object that has at least one virtual function contains a pointer to a run time virtual

function table. The virtual function table contains the starting addresses of all virtual

functions declared in the class.

o When a virtual function is called through a pointer or reference, the run time system

uses the object’s address to access the pointer to the virtual function table, follows the

pointer to the table, looks up the address of the function and calls the function.

Example: class mammal {public: virtual void F(); virtual void G(); }; class dog : public mammal {public: virtual void F(); virtual void G(); }; dog MyDog;

MyDog

VFT

F( )

G( )