c++
只有調用基類的指針和引用調用虛函數時,纔會發生動態綁定。ide
Derived d;//Derived是派生類,Base是基類 Base *ptr=&d;//積累指針指向派生類的對象 Base &ref=d;//基類引用做爲派生類的別名 Base b=d;//調用Base的拷貝函數用d構造b
ptr->函數名,調用派生類中的對應函數 ref.函數名,掉用派生類中的對應函數 b.函數名,調用基礎類中的對應函數
經過派生類對象訪問同名函數。這是靜態連編函數
經過基類對象的指針訪問同名函數。這也是靜態連編學習
經過基類對象的指針或引用訪問同名虛函數,這是動態連編(老師喜歡考的)this
class P{public:f(){.....}};//father class C:public P{public:f(){....}};//son main(){ P* ptr; P p; C c; ptr=&p; ptr->f();//調用P::f() ptr=&c; ptr->f();//調用P::f() }
注意:要是沒有vitural,指針什麼類型就調用什麼類型spa
class A { public: virtual void foo() {} void bar() {} }; class B : public A { public: void foo() const override { // 錯誤: B::foo 不覆寫 A::foo } // (簽名不匹配) void foo() override; // OK : B::foo 覆寫 A::foo void bar() override {} // 錯誤: A::bar 非虛 }; void B::foo() override {// 錯誤: override只能放到類內使用 }
class Animal { public: Animal(); ~Animal(); virtual Animal& speak() {//能夠只在父類中定義vitural return *this;//注意必定要在每個覆寫的後面加上這個返回 } }; class Dog:public Animal { public: Dog(); ~Dog(); Dog& speak() { cout << "wang" << endl; delete this; return *this; } }; void test(Animal& p){//注意:覆寫以後暫時尚未效果,必需要定義一個void函數來調用,固然是用下面的方式來調用啦 p.speak(); }
struct Base { virtual void foo(); }; struct A : Base { void foo() final; // A::foo 被覆寫且是最終覆寫 void bar() final; // 錯誤:非虛函數不能被覆寫或是 final }; struct B final : A // struct B 爲 final,不能被繼承 { void foo() override; // 錯誤: foo 不能被覆寫,由於它在 A 中是 final };
特徵:指針
抽象類不能實例化。對象
抽象類能夠包含抽象方法和抽象訪問器。blog
從抽象類派生的非抽象類必須包括繼承的全部抽象方法和抽象訪問器的實際實現。繼承
必須是派生類來實現,而不是讓基類實現
使用狀況:下面會提到上轉和下轉,與其相似
// A function for displaying a Shape object void printObject(Shape &shape) { cout << "The area is " << shape.getArea() << endl; //這裏就是判斷是否是該類型是否是要轉換的類型,固然必須用到指針 Shape *p = &shape; Circle *c = dynamic_cast<Circle*>(p); // Circle& c = dynamic_cast<Circle&>(shape); // 引用轉換失敗則拋出一個異常 std::bad_cast if (c != nullptr) // 轉換失敗則指針爲空 { cout << "The radius is " << p1->getRadius() << endl; cout << "The diameter is " << p1->getDiameter() << endl; } }
上轉:upcasting : Assigning a pointer of a derived class type to a pointer of its base class type (將派生類類型指針賦值給基類類型指針)
Shape* s = nullptr; Circle *c = new Circle(2); s = c; //OK,隱式上轉
下轉:downcasting : Assigning a pointer of a base class type to a pointer of its derived class type. (將基類類型指針賦值給派生類類型指針)
Shape* s = new Circle(1); Circle *c = nullptr; c = dynamic_cast <Circle*> (s); //顯式下轉
好了,上面就是我對c++虛函數一些性質的簡單總結和用法