SlideShare a Scribd company logo
// Inheritance & upcasting
enum note { middleC, Csharp, Cflat }; // Etc.
class Instrument {
public:
void play(note) const {}
};
// Wind objects are Instruments
// because they have the same interface:
class Wind : public Instrument {};
void tune(Instrument& i) {
// ...
i.play(middleC);
}
int main() {
Wind flute;
tune(flute); // Upcasting
} ///:~
Inheritance Compiler Support
// Correctly creating the copy-constructor
#include <iostream>
using namespace std;
class Parent {
int i;
public:
Parent(int ii) : i(ii) {
cout << "Parent(int ii)n";
}
Parent(const Parent& b) : i(b.i) {
cout << "Parent(const Parent&)n";
}
Parent() : i(0) { cout << "Parent()n"; }
friend ostream&
operator<<(ostream& os, const Parent& b) {
return os << "Parent: " << b.i << endl;
}
};
Parameter Passing & Upcasting
class Member {
int i;
public:
Member(int ii) : i(ii) {
cout << "Member(int ii)n";
}
Member(const Member& m) : i(m.i) {
cout << "Member(const Member&)n";
}
friend ostream&
operator<<(ostream& os, const Member& m) {
return os << "Member: " << m.i << endl;
}
};
Parameter Passing & Upcasting
class Child : public Parent {
int i;
Member m;
public:
Child(int ii) : Parent(ii), i(ii), m(ii) {
cout << "Child(int ii)n";
}
friend ostream&
operator<<(ostream& os, const Child& c){
return os << (Parent&)c << c.m
<< "Child: " << c.i << endl;
}
};
int main() {
Child c(2);
cout << "calling copy-constructor: " << endl;
Child c2 = c; // Calls copy-constructor
cout << "values in c2:n" << c2;
} ///:~
Parameter Passing & Upcasting
Wind w;
Instrument* ip = &w; // Upcast
Instrument& ir = w; // Upcast
Pointer & Reference Upcasting
// Pure virtual base definitions
#include <iostream>
using namespace std;
class Pet {
public:
virtual void speak() const = 0;
virtual void eat() const = 0;
// Inline pure virtual definitions illegal:
//! virtual void sleep() const = 0 {}
};
// OK, not defined inline
void Pet::eat() const {
cout << "Pet::eat()" << endl;
}
void Pet::speak() const {
cout << "Pet::speak()" << endl;
}
Pure Virtual Definitions
class Dog : public Pet {
public:
// Use the common Pet code:
void speak() const { Pet::speak(); }
void eat() const { Pet::eat(); }
};
int main() {
Dog simba; // Richard's dog
simba.speak();
simba.eat();
} ///:~
Pure Virtual Definitions
//: C15:DynamicCast.cpp
#include <iostream>
using namespace std;
class Pet { public: virtual ~Pet(){}};
class Dog : public Pet {};
class Cat : public Pet {};
int main() {
Pet* b = new Cat; // Upcast
// Try to cast it to Dog*:
Dog* d1 = dynamic_cast<Dog*>(b);
// Try to cast it to Cat*:
Cat* d2 = dynamic_cast<Cat*>(b);
cout << "d1 = " << (long)d1 << endl;
cout << "d2 = " << (long)d2 << endl;
} ///:~
Downcasting: dynamic_cast
// Navigating class hierarchies with static_cast
#include <iostream>
#include <typeinfo>
using namespace std;
class Shape { public: virtual ~Shape() {}; };
class Circle : public Shape {};
class Square : public Shape {};
class Other {};
int main() {
Circle c;
Shape* s = &c; // Upcast: normal and OK
// More explicit but unnecessary:
s = static_cast<Shape*>(&c);
// (Since upcasting is such a safe and common
// operation, the cast becomes cluttering)
Circle* cp = 0;
Square* sp = 0;
RTTI
// Static Navigation of class hierarchies
// requires extra type information:
if(typeid(s) == typeid(cp)) // C++ RTTI
cp = static_cast<Circle*>(s);
if(typeid(s) == typeid(sp))
sp = static_cast<Square*>(s);
if(cp != 0)
cout << "It's a circle!" << endl;
if(sp != 0)
cout << "It's a square!" << endl;
// Static navigation is ONLY an efficiency hack;
// dynamic_cast is always safer. However:
// Other* op = static_cast<Other*>(s);
// Conveniently gives an error message, while
Other* op2 = (Other*)s;
// does not
} ///:~
RTTI
// Returning a pointer or reference to a derived
// type during overriding
#include <iostream>
#include <string>
using namespace std;
class PetFood {
public:
virtual string foodType() const = 0;
};
class Pet {
public:
virtual string type() const = 0;
virtual PetFood* eats() = 0;
};
Variant Return Type
class Bird : public Pet {
public:
string type() const { return "Bird"; }
class BirdFood : public PetFood {
public:
string foodType() const {
return "Bird food";
}
};
// Upcast to base type:
PetFood* eats() { return &bf; }
private:
BirdFood bf;
};
Variant Return Type
class Cat : public Pet {
public:
string type() const { return "Cat"; }
class CatFood : public PetFood {
public:
string foodType() const { return "Birds"; }
};
// Return exact type instead:
CatFood* eats() { return &cf; }
private:
CatFood cf;
};
Variant Return Type
int main() {
Bird b;
Cat c;
Pet* p[] = { &b, &c, };
for(int i = 0; i < sizeof p / sizeof *p; i++)
cout << p[i]->type() << " eats “<< p[i]->eats()->foodType() << endl;
// Can return the exact type:
Cat::CatFood* cf = c.eats();
Bird::BirdFood* bf;
// Cannot return the exact type:
//! bf = b.eats();
// Must downcast:
bf = dynamic_cast<Bird::BirdFood*>(b.eats());
} ///:~
Variant Return Type
// Behavior of virtual vs. non-virtual destructor
#include <iostream>
using namespace std;
class Base1 {
public:
~Base1() { cout << "~Base1()n"; }
};
class Derived1 : public Base1 {
public:
~Derived1() { cout << "~Derived1()n"; }
};
class Base2 {
public:
virtual ~Base2() { cout << "~Base2()n"; }
};
class Derived2 : public Base2 {
public:
~Derived2() { cout << "~Derived2()n"; }
};
Virtual Destructors
int main() {
Base1* bp = new Derived1; // Upcast
delete bp;
Base2* b2p = new Derived2; // Upcast
delete b2p;
} ///:~
Virtual Destructors
// Pure virtual destructors
// seem to behave strangely
class AbstractBase {
public:
virtual ~AbstractBase() = 0;
};
AbstractBase::~AbstractBase() {}
class Derived : public AbstractBase {};
// No overriding of destructor necessary?
int main() { Derived d; } ///:~
Pure Virtual Destructors
// Pure virtual destructors require a function body
class Pet {
public:
virtual ~Pet() = 0;
};
Pet::~Pet() {
cout << "~Pet()" << endl;
}
class Dog : public Pet {
public:
~Dog() {
cout << "~Dog()" << endl;
}
};
int main() {
Pet* p = new Dog; // Upcast
delete p; // Virtual destructor call
} ///:~
Pure Virtual Destructors
// Virtual calls inside destructors
class Base {
public:
virtual ~Base() {
cout << "Base1()n";
f();
}
virtual void f() { cout << "Base::f()n"; }
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived()n"; }
void f() { cout << "Derived::f()n"; }
};
int main() {
Base* bp = new Derived; // Upcast
delete bp;
} ///:~
Virtual Function Call in
Destructors
Same Behaviour
seen in Constructors
// Polymorphism with overloaded operators
#include <iostream>
using namespace std;
class Matrix;
class Scalar;
class Vector;
class Math {
public:
virtual Math& operator*(Math& rv) = 0;
virtual Math& multiply(Matrix*) = 0;
virtual Math& multiply(Scalar*) = 0;
virtual Math& multiply(Vector*) = 0;
virtual ~Math() {}
};
Operator Overloading: Virtual
class Matrix : public Math {
public:
Math& operator*(Math& rv) {
return rv.multiply(this); // 2nd dispatch
}
Math& multiply(Matrix*) {
cout << "Matrix * Matrix" << endl;
return *this;
}
Math& multiply(Scalar*) {
cout << "Scalar * Matrix" << endl;
return *this;
}
Math& multiply(Vector*) {
cout << "Vector * Matrix" << endl;
return *this;
}
};
Operator Overloading: Virtual
class Scalar : public Math {
public:
Math& operator*(Math& rv) {
return rv.multiply(this); // 2nd dispatch
}
Math& multiply(Matrix*) {
cout << "Matrix * Scalar" << endl;
return *this;
}
Math& multiply(Scalar*) {
cout << "Scalar * Scalar" << endl;
15: Polymorphism & Virtual Functions 711
return *this;
}
Math& multiply(Vector*) {
cout << "Vector * Scalar" << endl;
return *this;
}
};
Operator Overloading: Virtual
class Vector : public Math {
public:
Math& operator*(Math& rv) {
return rv.multiply(this); // 2nd dispatch
}
Math& multiply(Matrix*) {
cout << "Matrix * Vector" << endl;
return *this;
}
Math& multiply(Scalar*) {
cout << "Scalar * Vector" << endl;
return *this;
}
Math& multiply(Vector*) {
cout << "Vector * Vector" << endl;
return *this;
}
};
Operator Overloading: Virtual
int main() {
Matrix m; Vector v; Scalar s;
Math* math[] = { &m, &v, &s };
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++) {
Math& m1 = *math[i];
Math& m2 = *math[j];
m1 * m2;
}
} ///:~
Operator Overloading: Virtual

More Related Content

KEY
Beauty and Power of Go
KEY
PDF
Pl python python w postgre-sql
PDF
Go serving: Building server app with go
PDF
Vim Script Programming
PDF
Happy Go Programming
PPTX
A Few Interesting Things in Apple's Swift Programming Language
PDF
Swift Programming Language
Beauty and Power of Go
Pl python python w postgre-sql
Go serving: Building server app with go
Vim Script Programming
Happy Go Programming
A Few Interesting Things in Apple's Swift Programming Language
Swift Programming Language

What's hot (20)

PDF
Swift Programming Language
PPT
PPTX
Introducing PHP Latest Updates
PDF
Swiftの関数型っぽい部分
PPTX
Groovy
KEY
Sbaw091006
PDF
A swift introduction to Swift
PPT
C++totural file
PDF
Hello Swift 3/5 - Function
PDF
Introduction to Swift programming language.
PDF
Code Generation in PHP - PHPConf 2015
PDF
ECMAScript 6
ODP
EcmaScript 6
PPT
Unix 5 en
PPT
Developing iOS apps with Swift
ODP
OpenGurukul : Language : PHP
ODP
OpenGurukul : Language : Python
PDF
Hypers and Gathers and Takes! Oh my!
PDF
Happy Go Programming Part 1
PDF
Explaining ES6: JavaScript History and What is to Come
Swift Programming Language
Introducing PHP Latest Updates
Swiftの関数型っぽい部分
Groovy
Sbaw091006
A swift introduction to Swift
C++totural file
Hello Swift 3/5 - Function
Introduction to Swift programming language.
Code Generation in PHP - PHPConf 2015
ECMAScript 6
EcmaScript 6
Unix 5 en
Developing iOS apps with Swift
OpenGurukul : Language : PHP
OpenGurukul : Language : Python
Hypers and Gathers and Takes! Oh my!
Happy Go Programming Part 1
Explaining ES6: JavaScript History and What is to Come
Ad

Similar to Inheritance compiler support (20)

DOC
Virtual inheritance
PDF
C++ prgms 5th unit (inheritance ii)
PDF
Inheritance and polymorphism
PDF
Object Oriented Programming (OOP) using C++ - Lecture 4
PPTX
labwork practice on inhetitance-1.pptx
PPTX
Inheritance_PART2.pptx
PPT
PPT
inhertance c++
PDF
Oop Presentation
PDF
Object Oriented Programming (OOP) using C++ - Lecture 3
PPS
C++ Language
PPTX
Web2Day 2017 - Concilier DomainDriveDesign et API REST
PDF
3. Объекты, классы и пакеты в Java
PDF
C++ Programming - 12th Study
PPTX
RTTI and Namespaces.pptx ppt of c++ programming language
PDF
Easily mockingdependenciesinc++ 2
DOCX
Virtual function
PDF
VRaptor 4 - JavaOne
PPT
C++: Constructor, Copy Constructor and Assignment operator
PDF
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Virtual inheritance
C++ prgms 5th unit (inheritance ii)
Inheritance and polymorphism
Object Oriented Programming (OOP) using C++ - Lecture 4
labwork practice on inhetitance-1.pptx
Inheritance_PART2.pptx
inhertance c++
Oop Presentation
Object Oriented Programming (OOP) using C++ - Lecture 3
C++ Language
Web2Day 2017 - Concilier DomainDriveDesign et API REST
3. Объекты, классы и пакеты в Java
C++ Programming - 12th Study
RTTI and Namespaces.pptx ppt of c++ programming language
Easily mockingdependenciesinc++ 2
Virtual function
VRaptor 4 - JavaOne
C++: Constructor, Copy Constructor and Assignment operator
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Ad

More from Syed Zaid Irshad (20)

PDF
Data Structures & Algorithms - Spring 2025.pdf
PDF
Operating System.pdf
PDF
DBMS_Lab_Manual_&_Solution
PPTX
Data Structure and Algorithms.pptx
PPTX
Design and Analysis of Algorithms.pptx
PPTX
Professional Issues in Computing
PDF
Reduce course notes class xi
PDF
Reduce course notes class xii
PDF
Introduction to Database
PDF
C Language
PDF
Flowchart
PDF
Algorithm Pseudo
PDF
Computer Programming
PDF
ICS 2nd Year Book Introduction
PDF
Security, Copyright and the Law
PDF
Computer Architecture
PDF
Data Communication
PDF
Information Networks
PDF
Basic Concept of Information Technology
PDF
Introduction to ICS 1st Year Book
Data Structures & Algorithms - Spring 2025.pdf
Operating System.pdf
DBMS_Lab_Manual_&_Solution
Data Structure and Algorithms.pptx
Design and Analysis of Algorithms.pptx
Professional Issues in Computing
Reduce course notes class xi
Reduce course notes class xii
Introduction to Database
C Language
Flowchart
Algorithm Pseudo
Computer Programming
ICS 2nd Year Book Introduction
Security, Copyright and the Law
Computer Architecture
Data Communication
Information Networks
Basic Concept of Information Technology
Introduction to ICS 1st Year Book

Recently uploaded (20)

PPTX
Sustainable Sites - Green Building Construction
PPTX
Internet of Things (IOT) - A guide to understanding
DOCX
573137875-Attendance-Management-System-original
PPTX
OOP with Java - Java Introduction (Basics)
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PPTX
Lesson 3_Tessellation.pptx finite Mathematics
PDF
PPT on Performance Review to get promotions
PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PPTX
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
PDF
Structs to JSON How Go Powers REST APIs.pdf
PDF
Well-logging-methods_new................
PPTX
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PPT
Mechanical Engineering MATERIALS Selection
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPTX
Lecture Notes Electrical Wiring System Components
PPTX
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PDF
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PDF
Arduino robotics embedded978-1-4302-3184-4.pdf
Sustainable Sites - Green Building Construction
Internet of Things (IOT) - A guide to understanding
573137875-Attendance-Management-System-original
OOP with Java - Java Introduction (Basics)
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Lesson 3_Tessellation.pptx finite Mathematics
PPT on Performance Review to get promotions
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
Structs to JSON How Go Powers REST APIs.pdf
Well-logging-methods_new................
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
Mechanical Engineering MATERIALS Selection
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
Lecture Notes Electrical Wiring System Components
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
Arduino robotics embedded978-1-4302-3184-4.pdf

Inheritance compiler support

  • 1. // Inheritance & upcasting enum note { middleC, Csharp, Cflat }; // Etc. class Instrument { public: void play(note) const {} }; // Wind objects are Instruments // because they have the same interface: class Wind : public Instrument {}; void tune(Instrument& i) { // ... i.play(middleC); } int main() { Wind flute; tune(flute); // Upcasting } ///:~ Inheritance Compiler Support
  • 2. // Correctly creating the copy-constructor #include <iostream> using namespace std; class Parent { int i; public: Parent(int ii) : i(ii) { cout << "Parent(int ii)n"; } Parent(const Parent& b) : i(b.i) { cout << "Parent(const Parent&)n"; } Parent() : i(0) { cout << "Parent()n"; } friend ostream& operator<<(ostream& os, const Parent& b) { return os << "Parent: " << b.i << endl; } }; Parameter Passing & Upcasting
  • 3. class Member { int i; public: Member(int ii) : i(ii) { cout << "Member(int ii)n"; } Member(const Member& m) : i(m.i) { cout << "Member(const Member&)n"; } friend ostream& operator<<(ostream& os, const Member& m) { return os << "Member: " << m.i << endl; } }; Parameter Passing & Upcasting
  • 4. class Child : public Parent { int i; Member m; public: Child(int ii) : Parent(ii), i(ii), m(ii) { cout << "Child(int ii)n"; } friend ostream& operator<<(ostream& os, const Child& c){ return os << (Parent&)c << c.m << "Child: " << c.i << endl; } }; int main() { Child c(2); cout << "calling copy-constructor: " << endl; Child c2 = c; // Calls copy-constructor cout << "values in c2:n" << c2; } ///:~ Parameter Passing & Upcasting
  • 5. Wind w; Instrument* ip = &w; // Upcast Instrument& ir = w; // Upcast Pointer & Reference Upcasting
  • 6. // Pure virtual base definitions #include <iostream> using namespace std; class Pet { public: virtual void speak() const = 0; virtual void eat() const = 0; // Inline pure virtual definitions illegal: //! virtual void sleep() const = 0 {} }; // OK, not defined inline void Pet::eat() const { cout << "Pet::eat()" << endl; } void Pet::speak() const { cout << "Pet::speak()" << endl; } Pure Virtual Definitions
  • 7. class Dog : public Pet { public: // Use the common Pet code: void speak() const { Pet::speak(); } void eat() const { Pet::eat(); } }; int main() { Dog simba; // Richard's dog simba.speak(); simba.eat(); } ///:~ Pure Virtual Definitions
  • 8. //: C15:DynamicCast.cpp #include <iostream> using namespace std; class Pet { public: virtual ~Pet(){}}; class Dog : public Pet {}; class Cat : public Pet {}; int main() { Pet* b = new Cat; // Upcast // Try to cast it to Dog*: Dog* d1 = dynamic_cast<Dog*>(b); // Try to cast it to Cat*: Cat* d2 = dynamic_cast<Cat*>(b); cout << "d1 = " << (long)d1 << endl; cout << "d2 = " << (long)d2 << endl; } ///:~ Downcasting: dynamic_cast
  • 9. // Navigating class hierarchies with static_cast #include <iostream> #include <typeinfo> using namespace std; class Shape { public: virtual ~Shape() {}; }; class Circle : public Shape {}; class Square : public Shape {}; class Other {}; int main() { Circle c; Shape* s = &c; // Upcast: normal and OK // More explicit but unnecessary: s = static_cast<Shape*>(&c); // (Since upcasting is such a safe and common // operation, the cast becomes cluttering) Circle* cp = 0; Square* sp = 0; RTTI
  • 10. // Static Navigation of class hierarchies // requires extra type information: if(typeid(s) == typeid(cp)) // C++ RTTI cp = static_cast<Circle*>(s); if(typeid(s) == typeid(sp)) sp = static_cast<Square*>(s); if(cp != 0) cout << "It's a circle!" << endl; if(sp != 0) cout << "It's a square!" << endl; // Static navigation is ONLY an efficiency hack; // dynamic_cast is always safer. However: // Other* op = static_cast<Other*>(s); // Conveniently gives an error message, while Other* op2 = (Other*)s; // does not } ///:~ RTTI
  • 11. // Returning a pointer or reference to a derived // type during overriding #include <iostream> #include <string> using namespace std; class PetFood { public: virtual string foodType() const = 0; }; class Pet { public: virtual string type() const = 0; virtual PetFood* eats() = 0; }; Variant Return Type
  • 12. class Bird : public Pet { public: string type() const { return "Bird"; } class BirdFood : public PetFood { public: string foodType() const { return "Bird food"; } }; // Upcast to base type: PetFood* eats() { return &bf; } private: BirdFood bf; }; Variant Return Type
  • 13. class Cat : public Pet { public: string type() const { return "Cat"; } class CatFood : public PetFood { public: string foodType() const { return "Birds"; } }; // Return exact type instead: CatFood* eats() { return &cf; } private: CatFood cf; }; Variant Return Type
  • 14. int main() { Bird b; Cat c; Pet* p[] = { &b, &c, }; for(int i = 0; i < sizeof p / sizeof *p; i++) cout << p[i]->type() << " eats “<< p[i]->eats()->foodType() << endl; // Can return the exact type: Cat::CatFood* cf = c.eats(); Bird::BirdFood* bf; // Cannot return the exact type: //! bf = b.eats(); // Must downcast: bf = dynamic_cast<Bird::BirdFood*>(b.eats()); } ///:~ Variant Return Type
  • 15. // Behavior of virtual vs. non-virtual destructor #include <iostream> using namespace std; class Base1 { public: ~Base1() { cout << "~Base1()n"; } }; class Derived1 : public Base1 { public: ~Derived1() { cout << "~Derived1()n"; } }; class Base2 { public: virtual ~Base2() { cout << "~Base2()n"; } }; class Derived2 : public Base2 { public: ~Derived2() { cout << "~Derived2()n"; } }; Virtual Destructors
  • 16. int main() { Base1* bp = new Derived1; // Upcast delete bp; Base2* b2p = new Derived2; // Upcast delete b2p; } ///:~ Virtual Destructors
  • 17. // Pure virtual destructors // seem to behave strangely class AbstractBase { public: virtual ~AbstractBase() = 0; }; AbstractBase::~AbstractBase() {} class Derived : public AbstractBase {}; // No overriding of destructor necessary? int main() { Derived d; } ///:~ Pure Virtual Destructors
  • 18. // Pure virtual destructors require a function body class Pet { public: virtual ~Pet() = 0; }; Pet::~Pet() { cout << "~Pet()" << endl; } class Dog : public Pet { public: ~Dog() { cout << "~Dog()" << endl; } }; int main() { Pet* p = new Dog; // Upcast delete p; // Virtual destructor call } ///:~ Pure Virtual Destructors
  • 19. // Virtual calls inside destructors class Base { public: virtual ~Base() { cout << "Base1()n"; f(); } virtual void f() { cout << "Base::f()n"; } }; class Derived : public Base { public: ~Derived() { cout << "~Derived()n"; } void f() { cout << "Derived::f()n"; } }; int main() { Base* bp = new Derived; // Upcast delete bp; } ///:~ Virtual Function Call in Destructors Same Behaviour seen in Constructors
  • 20. // Polymorphism with overloaded operators #include <iostream> using namespace std; class Matrix; class Scalar; class Vector; class Math { public: virtual Math& operator*(Math& rv) = 0; virtual Math& multiply(Matrix*) = 0; virtual Math& multiply(Scalar*) = 0; virtual Math& multiply(Vector*) = 0; virtual ~Math() {} }; Operator Overloading: Virtual
  • 21. class Matrix : public Math { public: Math& operator*(Math& rv) { return rv.multiply(this); // 2nd dispatch } Math& multiply(Matrix*) { cout << "Matrix * Matrix" << endl; return *this; } Math& multiply(Scalar*) { cout << "Scalar * Matrix" << endl; return *this; } Math& multiply(Vector*) { cout << "Vector * Matrix" << endl; return *this; } }; Operator Overloading: Virtual
  • 22. class Scalar : public Math { public: Math& operator*(Math& rv) { return rv.multiply(this); // 2nd dispatch } Math& multiply(Matrix*) { cout << "Matrix * Scalar" << endl; return *this; } Math& multiply(Scalar*) { cout << "Scalar * Scalar" << endl; 15: Polymorphism & Virtual Functions 711 return *this; } Math& multiply(Vector*) { cout << "Vector * Scalar" << endl; return *this; } }; Operator Overloading: Virtual
  • 23. class Vector : public Math { public: Math& operator*(Math& rv) { return rv.multiply(this); // 2nd dispatch } Math& multiply(Matrix*) { cout << "Matrix * Vector" << endl; return *this; } Math& multiply(Scalar*) { cout << "Scalar * Vector" << endl; return *this; } Math& multiply(Vector*) { cout << "Vector * Vector" << endl; return *this; } }; Operator Overloading: Virtual
  • 24. int main() { Matrix m; Vector v; Scalar s; Math* math[] = { &m, &v, &s }; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { Math& m1 = *math[i]; Math& m2 = *math[j]; m1 * m2; } } ///:~ Operator Overloading: Virtual

Editor's Notes

  • #11: Not out of hierarchy: Safer than typical cast
  • #12: Not out of hierarchy: Safer than typical cast
  • #13: Not out of hierarchy: Safer than typical cast
  • #14: Not out of hierarchy: Safer than typical cast
  • #15: Not out of hierarchy: Safer than typical cast
  • #16: Not out of hierarchy: Safer than typical cast
  • #17: Not out of hierarchy: Safer than typical cast
  • #18: Not out of hierarchy: Safer than typical cast
  • #19: Not out of hierarchy: Safer than typical cast
  • #20: Not out of hierarchy: Safer than typical cast
  • #21: Not out of hierarchy: Safer than typical cast
  • #22: Not out of hierarchy: Safer than typical cast
  • #23: Not out of hierarchy: Safer than typical cast
  • #24: Not out of hierarchy: Safer than typical cast
  • #25: Not out of hierarchy: Safer than typical cast