CS计算机代考程序代写 compiler flex c++ INTRO TO COMPUTER SCIENCE II

INTRO TO COMPUTER SCIENCE II
POLYMORPHISM (CONT.)
CS162

Last time…
 Polymorphism
Virtual functions
2 specifiers that can be used

Last time…
 Polymorphism
When a call to a member function executes different code depending on the
type of object that invokes the function Virtual functions
 Special type of function that resolves to the most derived version of the function that exists between the base and derived class
 2 specifiers that can be used: override & final
//in animal.h
virtual string get_name();
virtual void make_noise(int);
//in monkey.h
string get_name() override;
void make_noise(int) final;

Abstract Polymorphism
Abstract function (pure virtual function)
 No definition in the base class, but child classes need to define it or you’ll get an error when you try to create a derived object
virtual void move_forward(int) = 0;
Abstract class
 Any class that has one or more pure virtual
 An abstract class object cannot be instantiated
 But you can use pointers & references to abstract class types
prog.cpp:19:9: error: cannot declare variable ‘m1’ to be of abstract type ‘Monkey’
Monkey m1(“Curious George”);
In file included from prog.cpp:3:0:
monkey.h:12:7: note: because the following virtual functions are pure within Monkey’:
class Monkey : public Animal {
In file included from prog.cpp:2:0:
animal.h:25:18: note: virtual void Animal::move_forward(int)
virtual void move_forward(int) = 0;
prog.cpp: In function ‘int main()’:
prog.cpp:15:9: error: cannot declare variable ‘a1’ to be of abstract type ‘Animal’
Animal a1(“Curious George”);
In file included from prog.cpp:2:0:
animal.h:10:7: note: because the following virtual functions are pure within Animal’:
class Animal {
animal.h:25:18: note: virtual void Animal::move_forward(int) virtual void move_forward(int) = 0;
functions

Interface Classes
 A class with NO member variables, and where ALL of the functions are pure virtual/abstract
Useful when you want to define functionality derived classes must implement, but leave the details up to the derived class
class Shape { public:
virtual ~Shape();
virtual void move_x(distance x) = 0; virtual void move_y(distance y) = 0; virtual float area() = 0
//…
};
class Rectangle : public Shape { public:
virtual ~Rectangle(); void move_x(distance x); void move_y(distance y); float area();
private:
float width; float height; //…
};
No keyword in C++, just how you set it up

Inheritance & Polymorphism
Things that are not inherited  Constructors
 Destructors
 friends
Whenever you are dealing with inheritance, make any explicit destructors virtual
 Memory leaks if you delete a base class pointer pointing to a derived object
 virtual ~Base(); virtual ~Derived();

Vocabulary – Binding
 Binding
 The process used to convert identifiers into addresses (such as variables and function names)
Early binding/static binding
The default behavior in C++. A function call always executes the same version of code.
 The compiler is able to directly link the identifier name with an address Late binding/dynamic binding
 Used when the type of object is evaluated at runtime. The compiler generated code will check to determine the object type and then execute the correct version of code
 This is what allows C++ to support polymorphism (using the virtual keyword) Slightly less efficient, but more flexible

Inheritance & Objects
Recall that inheritance involves base classes and derived classes
In some cases, you might want to convert objects into different types
Let’s consider the hierarchy shown here
Animal
name, age make_noise() get_name()
Monkey
longest_jump get_name() make_noise()
Sea Otter
maximum_length, swim_speed make_noise()
swim()
Teal Sea
Otter
make_noise() swim()
Red Sea
Otter
make_noise() swim()

Object Slicing
What if we want to convert objects into different types?
 Say, convert a Red_Sea_Otter object into an Animal so that we can put it in array with other Animals
Object slicing is the assigning of a Derived class object to a Base class object
 “lose” any member variables that were specific to the Derived class
 Won’t be able to access derived functions
Derived d;
Base b = d;
//example of object
slicing
Red_Sea_Otter rso;
Animal a1 = rso;
//a1 has now “lost” any
member variables specific
to Red_Sea_Otter

Using pointers instead
Pointers and polymorphism allow us to treat an object as a different type without permanently losing data
Create an array of Animal pointers instead of storing Animal objects
Animal* array[2];
Monkey m1;
Red_Sea_Otter rso;
array[0] = &m1;
array[1] = &rso;
for (int i=0; i<2; i++;) array[i]->make_noise();
Animal Monkey
Sea Otter
Teal Sea Otter
Red Sea Otter

One detail…
It was easy to convert a Red_Sea_Otter pointer into an Animal pointer What about going in the opposite direction?
Red_Sea_Otter rso;
Animal* a_ptr = &rso;
//a_ptr is an Animal pointer
that points to a Red_Sea_Otter
//now attempt to convert this to
a Red_Sea_Otter pointer…
Red_Sea_Otter* r_ptr = a_ptr
prog.cpp: In function ‘int main()’:
prog.cpp:24:25: error: invalid conversion from ‘Animal*’ to ‘Red_Sea_Otter*’ [-fpermissive]
Red_Sea_Otter* r_ptr = a_ptr;

Static Object Casting
Operator used for converting between datatypes
Only works if base pointer actually points to the correct derived object and not
some other class
Doesn’t allow us to determine if pointer is actually valid
Doesn’t work if you have an array of pointers to random animals
If you accidentally try to cast a Monkey* into a Red_Sea_Otter*…bad things happen
Red_Sea_Otter rso;
Animal* aptr = &rso;
Red_Sea_Otter* r_ptr = static_cast(a_ptr);
r_ptr->swim(4);
// if a_ptr was not pointing to a Red_Sea_Otter, the cast
// will fail silently! (Causing a SEGFAULT later!)

Dynamic Casting
Operator used for converting base pointers to derived pointers
Useful when you don’t know what the type of the object is
You have an animal pointer, but don’t know what type of animal
Red_Sea_Otter rso;
Red_Sea_Otter* tmp;
Animal* aptr = &rso;
tmp = dynamic_cast(aptr);
if (tmp != nullptr){
tmp->swim(12);
} else {
} cout << “Red_Sea_Otter cast error” << endl; Cast is verified at runtime  If the cast was successful, you get a valid pointer  If unsuccessful, you get a nullptr Also works with references Let’s look at some code... Animals and Monkeys and Sea Otters oh my! Animal name, age make_noise() get_name() Monkey longest_jump get_name() make_noise() Sea Otter maximum_length, swim_speed make_noise() swim() Teal Sea Otter make_noise() swim() Red Sea Otter make_noise() swim()