<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C++ 對象模型

      1. 對象的內存布局
        • 非虛函數類對象
          • 對于不包含虛函數的類,對象的內存布局相對簡單,其成員變量按照聲明的順序依次存儲。例如:
            class SimpleClass {
            private:
                int num;
                double d;
            public:
                SimpleClass(int n, double dd) : num(n), d(dd) {}
            };
            
          • SimpleClass對象的內存中,首先存儲int類型的num,然后存儲double類型的d。假設int占4字節,double占8字節,那么一個SimpleClass對象的大小至少為12字節(考慮內存對齊等因素可能會有所增加)。
        • 包含虛函數的類對象
          • 如果一個類包含虛函數,對象的內存布局會包含一個虛函數表指針(vptr)。這個指針通常位于對象內存的開頭(不同編譯器可能有不同的實現方式)。例如:
            class VirtualClass {
            private:
                int num;
                double d;
            public:
                VirtualClass(int n, double dd) : num(n), d(dd) {}
                virtual void someVirtualFunction() {}
            };
            
          • VirtualClass對象的內存中,首先是虛函數表指針(通常在32位系統中占4字節,64位系統中占8字節),然后是成員變量numd。虛函數表是一個函數指針數組,存儲了類的虛函數地址。當調用虛函數時,通過這個虛函數表指針找到虛函數表,再根據表中的指針調用相應的函數。
      2. 繼承關系中的對象模型
        • 單繼承
          • 在單繼承關系中,派生類對象的內存布局是基類部分在前,派生類部分在后。例如:
            class Base {
            private:
                int baseNum;
            public:
                Base(int n) : baseNum(n) {}
            };
            
            class Derived : public Base {
            private:
                double derivedNum;
            public:
                Derived(int n, double d) : Base(n), derivedNum(d) {}
            };
            
          • Derived對象的內存中,首先是Base類的baseNum,然后是Derived類的derivedNum。如果Base類包含虛函數,那么Derived對象也會包含虛函數表指針(并且這個虛函數表指針會被正確初始化以反映Derived類的虛函數情況)。
        • 多繼承
          • 多繼承的對象模型較為復雜。例如,有類Base1Base2和派生類Derived
            class Base1 {
            private:
                int num1;
            public:
                Base1(int n) : num1(n) {}
            };
            
            class Base2 {
            private:
                double num2;
            public:
                Base2(double n) : num2(n) {}
            };
            
            class Derived : public Base1, public Base2 {
            private:
                char ch;
            public:
                Derived(int n, double d, char c) : Base1(n), Base2(d), ch(c) {}
            };
            
          • Derived對象的內存中,首先是Base1的部分(num1),然后是Base2的部分(num2),最后是Derived類特有的部分(ch)。如果基類包含虛函數,處理虛函數表指針會更加復雜,不同編譯器可能采用不同的策略來確保正確的虛函數調用。
      3. 對象的構造與析構
        • 構造函數順序
          • 在對象創建時,首先調用基類的構造函數,然后按照繼承順序依次調用派生類的構造函數。在構造函數內部,成員變量的初始化按照聲明的順序進行。例如,對于前面提到的Derived類:
            Derived(int n, double d, char c) : Base1(n), Base2(d), ch(c) {}
            
          • 首先調用Base1的構造函數初始化Base1部分,然后調用Base2的構造函數初始化Base2部分,最后初始化Derived類特有的ch成員。
        • 析構函數順序
          • 析構函數的調用順序與構造函數相反。當Derived類對象被銷毀時,首先調用Derived類的析構函數,然后按照與繼承順序相反的順序依次調用基類的析構函數。并且,如果基類的析構函數是虛函數,那么通過基類指針刪除派生類對象時,可以確保正確調用派生類的析構函數。例如:
            Base1* ptr = new Derived(1, 2.0, 'a');
            delete ptr;
            
          • 如果Base1的析構函數不是虛函數,只會調用Base1的析構函數,可能導致Derived類資源無法正確釋放;如果Base1的析構函數是虛函數,則會先調用Derived類的析構函數,再調用Base1的析構函數,正確釋放資源。
      4. 函數調用機制(特別是虛函數調用)
        • 非虛函數調用
          • 對于非虛函數,函數調用在編譯時就確定了。編譯器根據函數名和作用域直接生成調用代碼。例如:
            class NonVirtualClass {
            public:
                void nonVirtualFunction() {}
            };
            
            int main() {
                NonVirtualClass obj;
                obj.nonVirtualFunction();
                return 0;
            }
            
          • 編譯器直接知道obj.nonVirtualFunction()應該調用NonVirtualClass類中的nonVirtualFunction函數,不需要在運行時進行額外的查找。
        • 虛函數調用
          • 虛函數的調用是在運行時確定的。當通過基類指針或引用調用虛函數時,會根據對象實際的類型來決定調用哪個函數。例如:
            class Base {
            public:
                virtual void virtualFunction() {
                    std::cout << "Base::virtualFunction" << std::endl;
                }
            };
            
            class Derived : public Base {
            public:
                void virtualFunction() override {
                    std::cout << "Derived::virtualFunction" << std::endl;
                }
            };
            
            int main() {
                Base* ptr = new Derived();
                ptr->virtualFunction();
                return 0;
            }
            
          • 這里ptrBase類的指針,但實際指向Derived類對象。當調用ptr->virtualFunction()時,由于virtualFunction是虛函數,會在運行時根據ptr實際指向的對象類型(即Derived類)來調用Derived類中的virtualFunction函數。這種機制實現了多態性,使得代碼更加靈活和可擴展。
      posted @ 2024-10-06 21:33  西北野狼  閱讀(55)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国99久9在线 | 免费| √天堂中文www官网在线| 国产一级毛片高清完整视频版| 无码伊人久久大杳蕉中文无码 | 伊在人间香蕉最新视频| 国产精品爽爽久久久久久竹菊| 亚洲小说乱欧美另类| 人人澡人人透人人爽| 亚洲男人的天堂一区二区| 国产精品午夜福利精品| 林芝县| AV无码免费不卡在线观看| 欧美综合人人做人人爱| 2020年最新国产精品正在播放| 7878成人国产在线观看| 国产精品免费看久久久| 依安县| 亚洲人午夜精品射精日韩| 偷拍精品一区二区三区| 清远市| 久久91精品牛牛| 日本大片免A费观看视频三区| 午夜无码免费福利视频网址| 亚洲精品专区在线观看| 亚洲一区成人av在线| av一本久道久久波多野结衣| 精品国产综合成人亚洲区| 国产不卡的一区二区三区| 小鲜肉自慰网站xnxx| 九九热在线免费观看视频| 中文字幕日韩精品国产| 国产精品区一区第一页| 色熟妇人妻久久中文字幕| 永久免费无码av网站在线观看| 日韩无专区精品中文字幕| 国产人成777在线视频直播| 国产av国片精品一区二区| 久久91精品牛牛| 高清国产一区二区无遮挡| 一区二区三区午夜无码视频| 2021国产成人精品久久|