C++ åèæå
- C++11
- C++14
- C++17
- C++20
- C++ ç¼è¯å¨æ¯ææ åµè¡¨
- ç¬ç«ä¸å®¿ä¸»å®ç°
- C++ è¯è¨
- å鿍¡æ¿(C++14 èµ·)
- æ´æ°åé¢é
- èååå§å
- æ¯è¾è¿ç®ç¬¦
- é»è®¤æ¯è¾(C++20 èµ·)
- 转ä¹åºå
- for 循ç¯
- while 循ç¯
- ç¨æ·å®ä¹è½¬æ¢
- SFINAE
- 䏻彿°
- ASCII ç 表
- æ è¯ç¬¦
- ç±»å
- å 忍¡å
- 对象
- åºæ¬æ¦å¿µ
- 表达å¼
- 声æ
- åå§å
- 彿°
- è¯å¥
- ç±»
- è¿ç®ç¬¦éè½½
- 模æ¿
- å¼å¸¸
- äºå¡æ§å å
- å ä½ç¬¦ç±»å说æç¬¦ (C++11 èµ·)
- decltype 说æç¬¦
- 彿°å£°æ
- final 说æç¬¦ (C++11 èµ·)
- override 说æç¬¦(C++11 èµ·)
- å¼ç¨å£°æ
- ç§»å¨æé 彿°
- ç§»å¨èµå¼è¿ç®ç¬¦
- æä¸¾å£°æ
- constexpr 说æç¬¦(C++11 èµ·)
- å表åå§å (C++11 èµ·)
- æé 彿°ä¸æååå§åå¨å表
- using 声æ
- nullptrï¼æéåé¢é
- åºç¡ç±»å
- ç±»åå«åï¼å«å模ç (C++11 èµ·)
- å½¢åå
- èåä½å£°æ
- å符串åé¢é
- ç¨æ·å®ä¹åé¢é (C++11 èµ·)
- 屿§è¯´æç¬¦åºå(C++11 èµ·)
- Lambda è¡¨è¾¾å¼ (C++11 èµ·)
- noexcept 说æç¬¦ (C++11 èµ·)
- noexcept è¿ç®ç¬¦ (C++11 èµ·)
- alignof è¿ç®ç¬¦(C++11 èµ·)
- alignas 说æç¬¦ (C++11 èµ·)
- åå¨ç±»è¯´æç¬¦
- åºäºèå´ç for å¾ªç¯ (C++11 èµ·)
- static_assert 声æ
- éå¼è½¬æ¢
- 代ç¨è¿ç®ç¬¦è¡¨ç¤º
- èªå¢/èªåè¿ç®ç¬¦
- æå 表达å¼(C++17 èµ·)
- 类模æ¿å®åæ¨å¯¼(C++17 èµ·)
- 模æ¿å½¢å䏿¨¡æ¿å®å
- if è¯å¥
- inline 说æç¬¦
- ç»æåç»å®å£°æ (C++17 èµ·)
- switch è¯å¥
- å符åé¢é
- å½å空é´
- æ±å¼é¡ºåº
- å¤å¶æ¶é¤
- consteval 说æç¬¦ (C++20 èµ·)
- constinit 说æç¬¦ (C++20 èµ·)
- åç¨ (C++20)
- 模å (C++20 èµ·)
- 约æä¸æ¦å¿µ (C++20 èµ·)
- new 表达å¼
- do-while 循ç¯
- continue è¯å¥
- break è¯å¥
- goto è¯å¥
- return è¯å¥
- 卿å¼å¸¸è¯´æ
- throw 表达å¼
- try å
- å½å空é´å«å
- 类声æ
- cvï¼const ä¸ volatileï¼ç±»åéå®ç¬¦
- é»è®¤åå§å
- å¼åå§å(C++03 èµ·)
- é¶åå§å
- å¤å¶åå§å
- ç´æ¥åå§å
- 常éåå§å
- å¼ç¨åå§å
- å¼ç±»å«
- C++ è¿ç®ç¬¦ä¼å 级
- å¸å°åé¢é
- æµ®ç¹åé¢é
- typedef 说æç¬¦
- æ¾å¼ç±»å转æ¢
- static_cast 转æ¢
- dynamic_cast 转æ¢
- const_cast 转æ¢
- reinterpret_cast 转æ¢
- delete 表达å¼
- æé 彿°ä¸æååå§åå¨å表
- this æé
- 访é®è¯´æç¬¦
- åå 声æ
- virtual 彿°è¯´æç¬¦
- explicit 说æç¬¦
- éææå
- é»è®¤æé 彿°
- å¤å¶æé 彿°
- å¤å¶èµå¼è¿ç®ç¬¦
- ææå½æ°
- 类模æ¿
- 彿°æ¨¡æ¿
- æ¾å¼ï¼å ¨ï¼æ¨¡æ¿ç¹å
- æ±ç¼å£°æ
- C++ çåå²
- ä½ç¨å
- çåæ
- å®ä¹ä¸åä¸å®ä¹è§åï¼ODRï¼
- å忥æ¾
- æéå®çå忥æ¾
- æ éå®çå忥æ¾
- å¦åè§å
- æªå®ä¹è¡ä¸º
- ç¿»è¯é¶æ®µ
- 常é表达å¼
- èµå¼è¿ç®ç¬¦
- ç®æ¯è¿ç®ç¬¦
- é»è¾è¿ç®ç¬¦
- æå访é®è¿ç®ç¬¦
- å ¶ä»è¿ç®ç¬¦
- sizeof è¿ç®ç¬¦
- typeid è¿ç®ç¬¦
- æé声æ
- æ°ç»å£°æ
- è¯è¨é¾æ¥
- 详述类å说æç¬¦
- é»è®¤å®å
- åé¿å®å
- å®åä¾èµæ¥æ¾
- éè½½å³è®®
- éè½½å½æ°çå°å
- æ³¨å ¥ç±»å
- ééææ°æ®æå
- ééææå彿°
- åµå¥ç±»
- æ´¾çç±»
- 空åºç±»ä¼å
- æ½è±¡ç±»
- ä½å
- è½¬æ¢æé 彿°
- æå模æ¿
- 模æ¿å®åæ¨å¯¼
- é¨å模æ¿ç¹å
- sizeof... è¿ç®ç¬¦
- å¾ å³å
- 彿° try å
- æ©å å½åç©ºé´ std
- åæ¯ç¼©å
- RAII
- ä¸/äº/é¶ä¹æ³å
- PImpl
- é¶å¼éåå
- ç±»å
- éå¼è½¬æ¢
- 注é
- C++ å ³é®è¯
- é¢å¤çå¨
- C++ æ ååºå¤´æä»¶
- å ·åè¦æ±
- åè½ç¹æ§æµè¯ (C++20)
- å·¥å ·åº
- ç±»åæ¯æï¼åºæ¬ç±»åãRTTIãç±»åç¹æ§ï¼
- æ¦å¿µåº (C++20)
- é误å¤ç
- 卿å å管ç
- æ¥æåæ¶é´å·¥å ·
- å符串åº
- 容å¨åº
- è¿ä»£å¨åº
- èå´åº (C++20)
- ç®æ³åº
- æ°å¼åº
- è¾å ¥/è¾åºåº
- æä»¶ç³»ç»åº
- æ¬å°ååº
- æ£å表达å¼åº
- ååæä½åº
- çº¿ç¨æ¯æåº
- å®éªæ§ C++ ç¹æ§
- æç¨çèµæº
- ç´¢å¼
- std 符å·ç´¢å¼
- åç¨æ¯æ (C++20)
- C++ å ³é®è¯
ä½ç½®ï¼é¦é¡µ > C++ åèæå >C++ è¯è¨ > virtual 彿°è¯´æç¬¦
virtual 彿°è¯´æç¬¦
virtual 说æç¬¦æå®ééææå彿°ä¸ºè彿°å¹¶æ¯æå¨æè°ç¨æ´¾åãå®åªè½å¨ééææå彿°çé¦ä¸ªå£°æï¼å³å½å®äºç±»å®ä¹ä¸å£°ææ¶ï¼ç 声æè¯´æç¬¦åºå ä¸åºç°ã
è§£é
è彿°æ¯å¯å¨æ´¾çç±»ä¸è¦çå
¶è¡ä¸ºçæå彿°ãä¸éè彿°ç¸åï¼å³ä½¿æ²¡æå
³äºè¯¥ç±»å®é
ç±»åçç¼è¯æ¶ä¿¡æ¯ï¼ä»ç¶ä¿ç被è¦ççè¡ä¸ºãå½ä½¿ç¨å°åºç±»çæéæå¼ç¨æ¥å¤çæ´¾çç±»æ¶ï¼å¯¹è¢«è¦ççè彿°çè°ç¨ï¼å°ä¼è°ç¨å®ä¹äºæ´¾çç±»ä¸çè¡ä¸ºãå½ä½¿ç¨æéå®å忥æ¾ï¼å³å½æ°ååºç°å¨ä½ç¨åè§£æè¿ç®ç¬¦ :: çå³ä¾§ï¼æ¶ï¼æ¤è¡ä¸ºè¢«æå¶ã
#include <iostream> struct Base { virtual void f() { std::cout << "base\n"; } }; struct Derived : Base { void f() override { // 'override' å¯é std::cout << "derived\n"; } }; int main() { Base b; Derived d;  // éè¿å¼ç¨è°ç¨è彿° Base& br = b; // br çç±»åæ¯ Base& Base& dr = d; // dr çç±»å乿¯ Base& br.f(); // æå° "base" dr.f(); // æå° "derived"  // éè¿æéè°ç¨è彿° Base* bp = &b; // bp çç±»åæ¯ Base* Base* dp = &d; // dp çç±»å乿¯ Base* bp->f(); // æå° "base" dp->f(); // æå° "derived"  // éè彿°è°ç¨ br.Base::f(); // æå° "base" dr.Base::f(); // æå° "base" }
ç»è
è¥æä¸ªæå彿° vf å¨ç±» Base ä¸è¢«å£°æä¸º virtualï¼ä¸æä¸ªç´æ¥æé´æ¥æ´¾çäº Base çç±» Derived æ¥æä¸ä¸ªä¸åå 项ä¸ä¹ç¸åçæå彿°å£°æ
- åå
- å½¢åå表ï¼ä½éè¿åç±»åï¼
- cv éå®ç¬¦
- å¼ç¨éå®ç¬¦
åç±» Derived ä¸çæ¤å½æ°äº¦ä¸ºè彿°ï¼æ 论å
¶å£°æä¸æ¯å¦ä½¿ç¨å
³é®è¯ virtualï¼å¹¶è¦ç Base::vfï¼æ 论å
¶å£°æä¸æ¯å¦ä½¿ç¨åè¯ overrideï¼ã
è¦è¦çç Base::vf ä¸éè¦å¯è§ï¼å¯å£°æä¸º privateï¼æç¨ç§æç»§æ¿ç»§æ¿ï¼ã
class B { virtual void do_f(); // ç§ææå public: void f() { do_f(); } // å ¬å¼æ¥å£ }; struct D : public B { void do_f() override; // è¦ç B::do_f };  int main() { D d; B* bp = &d; bp->f(); // å é¨è°ç¨ D::do_f(); }
æ¯ä¸ªè彿°é½æå
¶æç»è¦ç彿°ï¼å®æ¯è¿è¡è彿°è°ç¨æ¶ææ§è¡ç彿°ãåºç±» Base çèæå彿° vf æ¯æç»è¦ç彿°ï¼é¤éæ´¾ç类声ææï¼éè¿å¤éç»§æ¿ï¼ç»§æ¿äºè¦ç vf çå¦ä¸ä¸ªå½æ°ã
struct A { virtual void f(); }; // A::f æ¯è彿° struct B : A { void f(); }; // B::f è¦ç A::f in B struct C : virtual B { void f(); }; // C::f è¦ç A::f in C struct D : virtual B {}; // D ä¸å¼å ¥è¦ç彿°ï¼B::f å¨ D ä¸ä¸ºæç» struct E : C, D { // E ä¸å¼å ¥è¦ç彿°ï¼C::f å¨ E ä¸ä¸ºæç» using A::f; // é彿°å£°æï¼ä» 令 A::f è½ä¸ºæ¥æ¾æè§ }; int main() { E e; e.f(); // èè°ç¨è°ç¨ C::fï¼e ä¸çæç»è¦ç彿° e.E::f(); // éèè°ç¨è°ç¨ A::fï¼å®å¨ E ä¸å¯è§ }
è¥ä¸ä¸ªå½æ°æ¥æå¤äºä¸ä¸ªæç»è¦ç彿°ï¼åç¨åºéè¯æï¼
struct A { virtual void f(); }; struct VB1 : virtual A { void f(); // è¦ç A::f }; struct VB2 : virtual A { void f(); // è¦ç A::f }; // struct Error : VB1, VB2 { // // é误ï¼A::f å¨ Error 䏿¥æä¸¤ä¸ªæç»è¦ç彿° // }; struct Okay : VB1, VB2 { void f(); // OKï¼è¿æ¯ A::f çæç»è¦ç彿° }; struct VB1a : virtual A {}; // ä¸å£°æè¦ç彿° struct Da : VB1a, VB2 { // Da ä¸ï¼A::f çæç»è¦ç彿°æ¯ VB2::f };
å ·æç¸åååä½ä¸åå½¢åå表ç彿°å¹¶ä¸è¦çååçåºç±»å½æ°ï¼ä½ä¼éèå®ï¼å¨æ éå®ååæ¥æ¾æ£æ¥æ´¾çç±»çä½ç¨åæ¶ï¼æ¥æ¾æ¾å°è¯¥å£°æèä¸åæ£æ¥åºç±»ã
struct B { virtual void f(); }; struct D : B { void f(int); // D::f éè B::fï¼é误çå½¢ååè¡¨ï¼ }; struct D2 : D { void f(); // D2::f è¦ç B::fï¼å®ä¸å¯è§ä¹ä¸è¦ç´§ï¼ };  int main() { B b; B& b_as_b = b; D d; B& d_as_b = d; D& d_as_d = d; D2 d2; B& d2_as_b = d2; D& d2_as_d = d2;  b_as_b.f(); // è°ç¨ B::f() d_as_b.f(); // è°ç¨ B::f() d2_as_b.f(); // è°ç¨ D2::f()  d_as_d.f(); // é误ï¼D ä¸çæ¥æ¾åªæ¾å° f(int) d2_as_d.f(); // é误ï¼D ä¸çæ¥æ¾åªæ¾å° f(int) }
|
è¥å½æ°ä»¥è¯´æç¬¦ struct B { virtual void f(int); }; struct D : B { virtual void f(int) override; // OKï¼D::f(int) è¦ç B::f(int) virtual void f(long) override; // é误ï¼f(long) ä¸è¦ç B::f(int) }; è¥å½æ°ä»¥è¯´æç¬¦ struct B { virtual void f() const final; }; struct D : B { void f() const; // é误ï¼D::f è¯å¾è¦ç final B::f }; |
(C++11 èµ·) |
éæå彿°åéææå彿°ä¸è½ä¸ºè彿°ã
彿°æ¨¡æ¿ä¸è½è¢«å£°æä¸º virtualãè¿åªéç¨äºèªèº«æ¯æ¨¡æ¿ç彿°ââ类模æ¿çå¸¸è§æå彿°å¯è¢«å£°æä¸ºè彿°ã
|
è彿°ï¼æ 论æ¯å£°æä¸º virtual è è¿æ¯è¦ç彿°ï¼ä¸è½æä»»ä½å ³èå¶çº¦ struct A { virtual void f() requires true; // é误ï¼åå¶çº¦çè彿° };
|
(C++20 èµ·) |
å¨ç¼è¯æ¶æ¿æ¢è彿°çé»è®¤å®åã
ååè¿åç±»å
è¥å½æ° Derived::f è¦ç Base::fï¼åå
¶è¿åç±»åå¿
é¡»è¦ä¹ç¸åè¦ä¹ä¸ºååï¼covariantï¼ã彿»¡è¶³ææä¸åè¦æ±æ¶ï¼ä¸¤ä¸ªç±»å为ååï¼
- 两个类åå为å°ç±»çæéæå¼ç¨ï¼å·¦å¼æå³å¼ï¼ãä¸å 许å¤çº§æéæå¼ç¨ã
-
Base::f()çè¿åç±»åä¸è¢«å¼ç¨/æåçç±»ï¼å¿ é¡»æ¯Derived::f()çè¿åç±»åä¸è¢«å¼ç¨/æåçç±»çæ æ§ä¹ä¸å¯è®¿é®çç´æ¥æé´æ¥åºç±»ã -
Derived::f()çè¿åç±»åå¿ é¡»æç¸å¯¹äºBase::f()çè¿åç±»åçç¸çæè¾å°ç cv éå®ã
Derived::f çè¿åç±»åä¸çç±»å¿
é¡»è¦ä¹æ¯ Derived èªèº«ï¼è¦ä¹å¿
é¡»æ¯äº Derived::f 声æç¹çæä¸ªå®æ´ç±»åã
è¿è¡è彿°è°ç¨æ¶ï¼æç»è¦ç彿°çè¿åç±»å被éå¼è½¬æ¢ææè°ç¨ç被è¦ç彿°çè¿åç±»åï¼
class B {};  struct Base { virtual void vf1(); virtual void vf2(); virtual void vf3(); virtual B* vf4(); virtual B* vf5(); };  class D : private B { friend struct Derived; // Derived ä¸ï¼B æ¯ D çå¯è®¿é®åºç±» };  class A; // å置声æçç±»æ¯ä¸å®æ´ç±»å  struct Derived : public Base { void vf1(); // è彿°ï¼è¦ç Base::vf1() void vf2(int); // éè彿°ï¼éè Base::vf2() // char vf3(); // é误ï¼è¦ç Base::vf3ï¼ä½å ·æä¸åä¸éååçè¿åç±»å D* vf4(); // è¦ç Base::vf4() å¹¶å ·æååçè¿åç±»å // A* vf5(); // é误ï¼A æ¯ä¸å®æ´ç±»å };  int main() { Derived d; Base& br = d; Derived& dr = d;  br.vf1(); // è°ç¨ Derived::vf1() br.vf2(); // è°ç¨ Base::vf2() // dr.vf2(); // é误ï¼vf2(int) éè vf2()  B* p = br.vf4(); // è°ç¨ Derived::vf4() å¹¶å°ç»æè½¬æ¢ä¸º B* D* q = dr.vf4(); // è°ç¨ Derived::vf4() èä¸å°ç»æè½¬æ¢ä¸º B*  }
èææå½æ°
è½ç¶ææå½æ°æ¯ä¸ç»§æ¿çï¼ä½è¥åºç±»å£°æå
¶ææå½æ°ä¸º virtualï¼åæ´¾ççææå½æ°å§ç»è¦çå®ãè¿ä½¿å¾å¯ä»¥éè¿æååºç±»çæé delete 卿åé
çå¤æç±»å对象
class Base { public: virtual ~Base() { /* éæ¾ Base çèµæº */ } };  class Derived : public Base { ~Derived() { /* éæ¾ Derived çèµæº */ } };  int main() { Base* b = new Derived; delete b; // è¿è¡å¯¹ Base::~Base() çè彿°è°ç¨ // ç±äºå®æ¯è彿°ï¼æ å®è°ç¨çæ¯ Derived::~Derived()ï¼ // è¿å°±è½éæ¾æ´¾çç±»çèµæºï¼ç¶åéµå¾ªéå¸¸çææé¡ºåº // è°ç¨ Base::~Base() }
æ¤å¤ï¼è¥ç±»æ¯å¤æçï¼å£°ææç»§æ¿äºè³å°ä¸ä¸ªè彿°ï¼ï¼ä¸å ¶ææå½æ°éèï¼åå é¤å®æ¯æªå®ä¹è¡ä¸ºï¼æ 论ä¸è°ç¨æ´¾ççææå½æ°æ¶æ¯å¦ä¼å¯¼è´èµæºæ³æ¼ã
䏿¡æç¨çæ¹éæ¯ï¼ä»»ä½åºç±»çææå½æ°å¿ é¡»ä¸ºå ¬å¼ä¸èï¼æåä¿æ¤ä¸éèã
卿é åæææé´
å½ä»æé 彿°æä»ææå½æ°ä¸ç´æ¥æé´æ¥è°ç¨è彿°ï¼å æ¬å¨ç±»çééææ°æ®æåçæé ææææé´ï¼ä¾å¦å¨æååå§åå¨å表ä¸ï¼ï¼ä¸å¯¹å ¶å®æ½è°ç¨çå¯¹è±¡æ¯æ£å¨æé æææä¸ç对象æ¶ï¼æè°ç¨ç彿°æ¯æé 彿°æææå½æ°çç±»ä¸çæç»è¦ç彿°ï¼èéè¿ä¸æ¥çæ´¾çç±»ä¸çè¦ç彿°ã æ¢è¨ä¹ï¼å¨æé åæææé´ï¼è¿ä¸æ¥çæ´¾ç类并ä¸åå¨ã
å½æå»ºå ·æå¤ä¸ªåæ¯çå¤æç±»æ¶ï¼å¨å±äºä¸ä¸ªåæ¯çæé 彿°å ï¼å¤æè¢«éå¶å°è¯¥ç±»åå ¶åºç±»ï¼è¥å®è·å¾äºæåè¿ä¸ªåå±çº§ä¹å¤çæä¸ªåºç±»å对象çæéæå¼ç¨ï¼ä¸è¯å¾è¿è¡è彿°è°ç¨ï¼ä¾å¦éè¿æ¾å¼æå访é®ï¼ï¼åè¡ä¸ºæªå®ä¹ï¼
struct V { virtual void f(); virtual void g(); };  struct A : virtual V { virtual void f(); // A::f æ¯ V::f å¨ A ä¸çæç»è¦ç彿° }; struct B : virtual V { virtual void g(); // B::g æ¯ V::g å¨ B ä¸çæç»è¦ç彿° B(V*, A*); }; struct D : A, B { virtual void f(); // D::f æ¯ V::f å¨ D ä¸çæç»è¦ç彿° virtual void g(); // D::g æ¯ V::g å¨ D ä¸çæç»è¦ç彿°  // 注æï¼A å¨ B ä¹ååå§å D() : B((A*)this, this) { } };  // B çæé 彿°ï¼ä» D çæé 彿°è°ç¨ B::B(V* v, A* a) { f(); // 对 V::f çèè°ç¨ï¼å°½ç®¡ D æ¥ææç»è¦ç彿°ï¼D ä¹ä¸åå¨ï¼ g(); // 对 B::g çèè°ç¨ï¼å¨ B 䏿¯æç»è¦ç彿°  v->g(); // v çç±»å V æ¯ B çåºç±»ï¼èè°ç¨å¦åè°ç¨ B::g  a->f(); // a çç±»å A 䏿¯ B çåºç±»ï¼å®å±äºå±çº§ä¸çä¸å忝ã // å°è¯éè¿è¿ä¸ªåæ¯è¿è¡èè°ç¨å¯¼è´æªå®ä¹è¡ä¸ºï¼ // å³ä½¿æ¤æ åµä¸ A 已宿æé // ï¼å®å¨ B ä¹åæé ï¼å 为å®å¨ D çåºç±»å表ä¸å äº B åºç°ï¼ // å®è·µä¸ï¼å¯¹ A::f çèè°ç¨ä¼è¯å¾ä½¿ç¨ B çèæå彿°è¡¨ï¼ // å 为å®å¨ B çæé æé´æ¯æ´»è·ç }
åé
- æ´¾çç±»åç»§æ¿æ¨¡å¼
- override 说æç¬¦ (C++11 èµ·)
- final 说æç¬¦ (C++11 èµ·)