Term
How do you get Polymorphic Behavior?
|
|
Definition
- You declare a pointer or a reference to the base class.
Base *ptr; or Base& b;
- You instantiate an object from the derived class.
b = Derived(); or
Derived d;
*ptr = &d; or
ptr = new Derived();
- Methods are declared as virtual
Base{
virtual f();
}
|
|
|
Term
class Base { public: void f(){cout << "Base" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Base base; base.f(); }
|
|
Definition
|
|
Term
class Base { public: void f(){cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Derived d; d.f(); }
|
|
Definition
|
|
Term
class Base { public: void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Base b = Derived(); b.f(); }
|
|
Definition
|
|
Term
class Base { public: void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Derived d = Base(); d.f(); }
|
|
Definition
ERROR
Base is-not-a Derived
but
Derived is-a Base |
|
|
Term
class Base { public: void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Base *b = new Derived(); b->f(); }
|
|
Definition
|
|
Term
class Base { public: void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() {cout << "Derived::f" << endl;} };
int main() { Derived d; Base &b = d; b.f(); }
|
|
Definition
|
|
Term
Now using virtual and override
class Base { public: virtual ~Base() = default; virtual void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() override {cout << "Derived::f" << endl;} };
int main() { Base *p = new Derived(); p->f(); delete p; }
|
|
Definition
|
|
Term
class Base { public: virtual ~Base() = default; virtual void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() override {cout << "Derived::f" << endl;} };
int main() { Base b = Derived(); b.f(); }
|
|
Definition
Base::f (virtual functions help when using pointers or references)
Also use static_cast for safety |
|
|
Term
class Base { public: virtual ~Base() = default; virtual void f() {cout << "Base::f" << endl;} };
class Derived : public Base { public: void f() override {cout << "Derived::f" << endl;} };
int main() { Derived d; Base &b = d; b.f(); }
|
|
Definition
Derived::f
Again, works for pointers and references |
|
|
Term
Does this output "Hitting Hammer"? If not why?
class Weapon { public: virtual ~Weapon() = default; void fire() { cout << "Firing Weapon" << endl;} };
class Gun : public Weapon { public: void fire() { cout << "Firing Gun";} };
class Hammer : public Weapon { public: void fire() { cout << "Hitting Hammer";} };
class Player { //Fields string name; int health; Weapon* weapon;
public: //Initialization Player(const string& name, const int& health, Weapon* weapon) :name(name), health(health), weapon(weapon) {} ~Player(){ delete weapon; }
//Using weapon void fire() { weapon->fire(); } };
int main() {
Player P("Gabool", 10, new Hammer()); P.fire();
}
|
|
Definition
Firing Weapon
Weapons fire function is not virtual, so All calls to a weapon's fire call uses base class. |
|
|
Term
A polymorphic class has virtual methods, but also needs a virtual ____ |
|
Definition
Deconstructor
If you dont then only base class deconstructor is called
If derived had allocated dynamic memory then memory leaks |
|
|
Term
class Base { public: ~Base() { // Non-virtual destructor cout << "Base destructor called" << endl; } };
class Derived : public Base { public: ~Derived() { // Destructor for Derived cout << "Derived destructor called" << endl; } };
int main() { Base* ptr = new Derived(); delete ptr; // Deletes through base class pointer return 0; }
|
|
Definition
|
|
Term
class Base { public: virtual ~Base() { virtual destructor cout << "Base destructor called" << endl; } };
class Derived : public Base { public: ~Derived(){ // Destructor for Derived cout << "Derived destructor called" << endl; } };
int main() { Base* ptr = new Derived(); delete ptr; // Deletes through base class pointer return 0; }
|
|
Definition
Derived destructor called
Base destructor called |
|
|
Term
If a class has at least 1 pure virtual function. Its called an Abstract class
What happens if I make an instance of an abstract class? |
|
Definition
ERROR, you cannot make any instances of an abstract class AT ALL. |
|
|
Term
How do you make an abstract Base class with only a pure virtual function f()? |
|
Definition
class Base { public: virtual ~Base() = default; virtual void f() = 0; virtual void g(); };
Still need a destructor (make it default or 0)
NOT USING DEFAULT OR 0 FOR DESTRUCTOR WILL NO LONGER MAKE IT ABSTARCT
BAD
class Base { public: virtual ~Base(); virtual void f(); };
|
|
|
Term
Is Derived a concrete class of Base?
class Base { public: virtual ~Base() = default; virtual void f() = 0; };
class Derived : public Base {};
int main() { Derived d; }
|
|
Definition
NO
A class that inherits pure virtual functions but doesnt implement them are abstract themselves. |
|
|
Term
Which one of these are allowed? Base is an abstract class
Base b(); Base b1(); Base b2(param); Base bs[];
void display(Base b);
|
|
Definition
NONE
All of these are making instances of Base (bs is making multiple instances) |
|
|
Term
Which one of these are valid?
Derived d; Base& b = d; Base* b1; Base* b2 = new Base(); void display(Base& base); void display(Base* base);
|
|
Definition
All... except b2, youre just making an instance of Base thats on the heap. |
|
|