<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # [23] 繼承 — 你所不知道的 ## FAQs in section [23]: * [23.1] 基類的非虛函數調用虛函數可以嗎? * [23.2] 上面那個FAQ讓我糊涂了。那是使用虛函數的另一種策略嗎? * [23.3] 當基類構造函數調用虛函數時,為什么不調用派生類重寫的該虛函數? * [23.4] 派生類可以重置(“覆蓋”)基類的非虛函數嗎? * [23.5] “`Warning:?Derived::f(float)?hides?Base::f(int)”`是什么意思? * [23.6] "virtual table" is an unresolved external 是什么意思? ## 23.1 基類的非虛函數調用虛函數可以嗎? 可以。有時(_并非總是!_)這是一個好主意。例如,假設所有`Shape`(圖形)對象有一個公共的打印算法。但這個算法依賴于它們的面積并且它們都有不同的方法來計算面積。在這種情況下,`Shape`的`area()`方法(譯注:得到`Shape`面積的成員函數)必須是virtual的(可能是純虛(pure-virtual)的),但`Shape::print()`可以在`Shape`中被定義為非虛(non-virtual)的,前提是所有派生類不會需要不同的打印算法。 ``` ?#include?"Shape.hpp" ?void?Shape::print()?const ?{ ?????float?a?=?this->area();??//?area()?為純虛 //?... ?} ``` ## 23.2 上面那個FAQ讓我糊涂了。那是使用虛函數的另一種策略嗎? 是的,那是不同的策略。是的,那的確是使用虛函數的兩種不同的基本方法: 1. 假設你遇到了上一個FAQ所描述的情況:每一個派生類都有一個結構完全一樣,只有一小塊不同的方法。因此算法是相同的,但實質不相同。在這種情況下,你最好在基類寫一個全面的算法作為`public:`方法(有時是非虛的),然后在派生類中寫那不同的一小塊。這一小塊在基類中聲明(通常是`protected:`的,純虛的,當然至少是`virtual`的),并且最終在每個派生類中被定義。這種情況下最緊要的問題是包含全面的算法的`public:`方法是否應該是`virtual`的。答案是,如果你認為某些派生類可能需要覆蓋它,就讓它成為`virtual`的。 2. 假設你遇到了上一個FAQ完全相反的情況,每一個派生類都有一個結構完全不同,但有一小塊的大多數(如果不是全部的話)相同的方法。在這種情況下,你最好將全面的算法放在最終在派生類中定義的`public:` `virtual`之中,并且將一小塊可以被只寫一次的公共代碼(避免代碼重復)隱藏在某處(任何地方!)。一般放在基類的`protected:`部分,但不是必須的,也可能不是最好的。找個地方隱藏它們就行了。注意,由于`public:`用戶不需要/不想做它們做的事情,如果在基類中隱藏它們,通常應該使它們是`protected:`的。假定它們是`protected:`的,那么可能不應該是`virtual`的:如果派生類不喜歡它們之一的行為,可以不必調用這個方法。 強調一下,以上列表中的是“既/又”情況,而不是“二者選一”的。換句話說,在任何給定的類上,不必在兩種策略中選擇。既有一個符合策略 #1 的方法`f()`,又有一個符合策略 #2 的方法`g()`是非常正常的。換句話說,在同一個類中,有兩種策略同時工作是非常正常的。 ## 23.3 當基類構造函數調用虛函數時,為什么不調用派生類重寫的該虛函數? 當基類被構造時,對象還不是一個派生類的對象,所以如果?`Base::Base()`調用了虛函數 `virt()`,則?`Base::virt()`?將被調用,即使?`Derived::virt()`(譯注:即派生類重寫的虛函數)存在。 同樣,當基類被析構時,對象已經不再是一個派生類對象了,所以如果?`Base::~Base()`調用了`virt()`,則?`Base::virt()`得到控制權,而不是重寫的?`Derived::virt()` 。 當你可以想象到如果?`Derived::virt()`?涉及到派生類的某個成員對象將造成的災難的時候,你很快就能看到這種方法的明智。詳細來說,如果?`Base::Base()`調用了虛函數?`virt()`,這個規則使得?`Base::virt()`被調用。如果不按照這個規則,`Derived::virt()`將在派生對象的派生部分被構造之前被調用,此時屬于派生對象的派生部分的某個成員對象還沒有被構造,而?`Derived::virt()`卻能夠訪問它。這將是災難。 ## 23.4 派生類可以重置(“覆蓋”)基類的非虛函數嗎? 合法但不合理。 有經驗的?C++?程序員有時會重新定義非虛函數(例如,派生類的實現可能可以更有效地利用派生類的資源),或者為了回避隱藏規則。即使非虛函數的指派基于指針/引用的靜態類型而不是指針/引用所指對象的動態類型,但其客戶可見性必須是一致的。 ## 23.5 “`Warning:?Derived::f(float)?hides?Base::f(int)`”?是什么意思? 意思是:你要完蛋了。 你所處的困境是:如果基類聲明了一個成員函數`f(int)`,并且派生類聲明了一個成員函數?`f(float)`(名稱相同,但參數類型和/或數量不同),那么?`Base`?的?`f(int)`被隱藏(hidden)而不是被重載(overloaded)或被重寫(overridden)(即使?基類的`f(int)`是虛擬的) 以下是你如何擺脫困境:派生類必須有一個被隱藏成員函數的`using`?聲明,例如: ``` ?class?Base?{ ?public: ???void?f(int); ?}; ?class?Derived?:?public?Base?{ ?public: ???using?Base::f;????//?This?un-hides?Base::f(int) ???void?f(double); ?}; ``` 如果你的編譯器不支持`using`語法,那么就重新定義基類的被隱藏的成員函數,即使它們是非虛的。一般來說這種重定義只不過使用`::`語法調用了基類被隱藏的成員函數,如, ``` ?class?Derived?:?public?Base?{ ?public: ???void?f(double); ???void?f(int?i)?{?Base::f(i);?}??//?The?redefinition?merely?calls?Base::f(int) ?}; ``` ## 23.6? "virtual table" is an unresolved external 是什么意思? 如果你得到一個連接錯誤"`Error:?Unresolved?or?undefined?symbols?detected:?virtual?table?for?class?Fred`",那么可能是你在?`Fred`?類中有一個未定義的虛成員函數。 編譯器通常會為含有虛函數的類創建一個稱為“虛函數表”的不可思議的數據結構(這就是它如何處理動態綁定的)。通常你根本不必知道它。但如果你忘了為`Fred`?類定義一個虛函數,則有時會得到這個連接錯誤。 許多編譯器將這個不可思議的“虛函數表”放進定義類的第一個非內聯虛函數的編輯單元中。因此如果?`Fred`?類的第一個非內聯虛函數是?`wilma()`,那么編譯器會將?`Fred`?的虛函數表放在?`Fred::wilma()`?所在的編輯單元里。不幸的是如果你意外的忘了定義?`Fred::wilma()`,那么你會得到一個"`Fred`'s virtual table is undefined"(`Fred`的虛函數表未定義)的錯誤而不是“`Fred::wilma()` is undefined”(`Fred::wilma()`未定義)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看