• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            (搬運工)當多態遇上數組

            Posted on 2012-02-15 16:46 點點滴滴 閱讀(277) 評論(0)  編輯 收藏 引用 所屬分類: 02 編程語言

            1. 能力測試

            請回答下面的問題:

            實現多態的效果,我們需要具備哪些條件?

            上面的題目僅用于測試你是否具備閱讀本文的必要條件。如果你對此題毫無頭緒,那么我建議你盡快交叉本文。當然,要順暢閱讀本文,你還需要具備一些C++、C++/CLI和C#的基礎知識。我想不必特別聲明,建議當然是主觀的。不過我愿意再說一次:建議是主觀的,你有選擇。

             

            2. ... In C++,

            好吧,既然你走到這一步,我建議你堅持下去。當然,你還是隨時可以交叉本文,總之,你有選擇。來,請先看看如下代碼:

             

            // Code #01

            #include
            #include

            class A
            {
            public:
            virtual void Print()
            {
            std::cout << "A" << std::endl;
            }

            }
            ;

            class B : public A
            {
            public:
            virtual void Print() override
            {
            std::cout << "B" << std::endl;
            }

            }
            ;

            class C : public A
            {
            public:
            virtual void Print() override
            {
            std::cout << "C" << std::endl;
            }

            }
            ;

            void Print(A arr[], int count)
            {
            for (int i = 0; i < count; ++i)
            {
            arr[i].Print();
            }

            }


            int _tmain(int argc, _TCHAR* argv[])
            {
            const int COUNT = 11;

            A a_arr[COUNT];
            Print(a_arr, COUNT);

            B b_arr[COUNT];
            Print(b_arr, COUNT);

            C c_arr[COUNT];
            Print(c_arr, COUNT);

            return 0;
            }

             

            • A:請告訴我,Code #01有沒有問題?
            • B:Easy job!把它編譯并運行一下就知道了唄!

            接著,阿B編譯了這段代碼,程序運行后,阿B發現輸出結果正是我們所期望的。于是,阿B得出結論:這段代碼沒問題!

            然而,你是否知道這段代碼其實隱藏著一個計時炸彈,只要時機一到,它就會引爆并使你的程序完全癱瘓?不信?那我只好讓你見識一下這個炸彈引爆是的情景了。現在,我分別為class B和class C加入一個field,并修改一下main()以便給class B和class C里的field賦值(注意,本賦值操作不是必須的!):

             

            // Code #02

            #include
            #include

            class A
            {
            public:
            virtual void Print()
            {
            std::cout << "A" << std::endl;
            }

            }
            ;

            class B : public A
            {
            public:
            virtual void Print() override
            {
            std::cout << "B" << std::endl;
            }


            long L;
            }
            ;

            class C : public A
            {
            public:
            virtual void Print() override
            {
            std::cout << "C" << std::endl;
            }


            double D;
            }
            ;

            void Print(A arr[], int count)
            {
            for (int i = 0; i < count; ++i)
            {
            arr[i].Print();
            }

            }


            int _tmain(int argc, _TCHAR* argv[])
            {
            const int COUNT = 11;

            A a_arr[COUNT];
            Print(a_arr, COUNT);

            B b_arr[COUNT];
            for (int i = 0; i < COUNT; ++i)
            {
            b_arr[i].L = 141214121412;
            }

            Print(b_arr, COUNT);

            C c_arr[COUNT];
            for (int i = 0; i < COUNT; ++i)
            {
            c_arr[i].D = 3.141592654;
            }

            Print(c_arr, COUNT);

            return 0;
            }

             

            計時炸彈終于被引爆了:

            可見程序無法找到b_arr[1]確切位置,其后果不會好過你在街上把一個背影看似相熟的女性誤認為是你的女朋友時所產生的尷尬。至于產生這個問題的原因,Scott Meyers已經在他的《More Effective C++》作了詳細的講解[1],這里我就沒必要重復勞動了。

            顯然,產生這個問題的根本原因是數組里的存放物長度不一致,如果能夠讓存放物的長度統一起來,問題就會迎刃而解了。問題男提出把指針放進數組,好吧,現在我們來看一下C++中多態與數組牽手的景象:

             

             

            // Code #02'
            // See Code #02 for Class A, Class B and Class C.

            void Print(A *arr[], int count)
            {
            for (int i = 0; i < count; ++i)
            {
            arr[i]->Print();
            }

            }


            int _tmain(int argc, _TCHAR* argv[])
            {
            const int COUNT = 11;

            A** a_arr =
            new A*[COUNT];
            B** b_arr =
            new B*[COUNT];
            C** c_arr =
            new C*[COUNT];
            for (int i = 0; i < COUNT; ++i)
            {
            a_arr[i] =
            new A;
            b_arr[i] =
            new B;
            b_arr[i]->L = 141214121412;
            c_arr[i] =
            new C;
            c_arr[i]->D = 3.141592654;
            }

            Print(a_arr, COUNT);
            Print(reinterpret_cast< A** >(b_arr), COUNT);
            Print(reinterpret_cast< A** >(c_arr), COUNT);

            return 0;
            }

             

            問題解決了,不過,我還是強烈建議你(當然,你有選擇!):

            在C++中,請盡量使用STL中的容器類來協助實現多態的效果。

             

            3. ... In C++/CLI,

            在C++/CLI的托管類型(Managed Type)中,只有ref class(或ref struct[2]可用于建立繼承體系。下面,我們來看看在C++/CLI中使用數組實現多態的情形:

             

            // Code #03

            using namespace System;
            using namespace stdcli::language;

            ref class A
            {
            public:
            virtual void Print()
            {
            Console::WriteLine("A");
            }

            }
            ;

            ref class B : public A
            {
            public:
            virtual void Print() override
            {
            Console::WriteLine("B");
            }


            long L;
            }
            ;

            ref class C : public A
            {
            public:
            virtual void Print() override
            {
            Console::WriteLine("C");
            }


            double D;
            }
            ;

            void Print(array< A^ >^ arr)
            {
            for (int i = 0; i < arr->Count; ++i)
            {
            arr[i]->Print();
            }

            }


            int _tmain()
            {
            const int COUNT = 11;

            array< A^ >^ a_arr = gcnew array< A^ >(COUNT);
            for (int i = 0; i < a_arr->Count; ++i)
            {
            a_arr[i] = gcnew A;
            }

            Print(a_arr);

            array< B^ >^ b_arr = gcnew array< B^ >(COUNT);
            for (int i = 0; i < b_arr->Count; ++i)
            {
            b_arr[i] = gcnew B;
            b_arr[i]->l = 141214121412;
            }

            Print(b_arr);

            array< C^ >^ c_arr = gcnew array< C^ >(COUNT);
            for (int i = 0; i < c_arr->Count; ++i)
            {
            c_arr[i] = gcnew C;
            c_arr[i]->d = 3.141592654;
            }

            Print(c_arr);
            }

             

             

            4. ... In C#,

            而在C#中,使用數組來實現多態又是如何的呢:

             

            // Code #04

            using System;

            class A
            {
            public virtual void Print()
            {
            Console.WriteLine("A");
            }

            }


            class B : A
            {
            public override void Print()
            {
            Console.WriteLine("B");
            }


            public long L;
            }


            class C : A
            {
            public override void Print()
            {
            Console.WriteLine("C") ;
            }


            public double D;
            }


            class Program
            {
            static void Main(string[] args)
            {
            const int COUNT = 11;

            A[] a_arr =
            new A[COUNT];
            for (int i = 0; i < a_arr.Length; i++)
            {
            a_arr[i] =
            new A();
            }

            Print(a_arr);

            B[] b_arr =
            new B[COUNT];
            for (int i = 0; i < b_arr.Length; i++)
            {
            b_arr[i] =
            new B();
            b_arr[i].L = 141214121412;
            }

            Print(b_arr);

            C[] c_arr =
            new C[COUNT];
            for (int i = 0; i < c_arr.Length; i++)
            {
            c_arr[i] =
            new C();
            c_arr[i].D = 3.141592654;
            }

            Print(c_arr);
            }


            public static void Print(A[] arr)
            {
            for (int i = 0; i < arr.Length; ++i)
            arr[i].Print();
            }

            }

             

             

            5. 牽手的條件

            其實,多態能夠牽上數組的手的條件很簡單:平等。回顧上面所有的代碼,我們不難發現,數組中的存放物等長是完成多態效果的必要條件,否則,編譯器將被誤導繼而生成有問題的程序。

             

            6. 關于舞臺

            Code #01、Code #02和Code #03都是使用Visual C++ 2005 Express Edition Beta 1來編輯和編譯的,其中Code #01和Code #02是標準的Win32 Console Application,而Code #03是.NET Console Application。Code #04是使用Visual C# 2005 Express Edition Beta 1來編輯和編譯的。

            精品久久亚洲中文无码| 久久久久久国产精品无码下载| 亚洲国产精品无码久久久久久曰| 久久久受www免费人成| 久久精品aⅴ无码中文字字幕不卡| 国产麻豆精品久久一二三| 久久男人中文字幕资源站| 久久久噜噜噜久久中文字幕色伊伊 | 2021久久国自产拍精品| 久久久国产精品| 无码久久精品国产亚洲Av影片| 国内精品久久久久影院网站| 亚洲综合伊人久久综合| 狠狠色伊人久久精品综合网 | 久久久久亚洲av无码专区喷水| 国产精品欧美久久久久无广告| 无码人妻少妇久久中文字幕蜜桃| 久久亚洲天堂| 99久久夜色精品国产网站| 久久久精品2019免费观看| 狠狠色丁香久久婷婷综合_中| 国内精品伊人久久久久| 香蕉久久夜色精品升级完成| 天堂无码久久综合东京热| 激情五月综合综合久久69| AV色综合久久天堂AV色综合在| 狠狠综合久久AV一区二区三区| 色天使久久综合网天天| 久久精品夜色噜噜亚洲A∨| 国产精品欧美久久久久天天影视| 97精品久久天干天天天按摩| 久久青青草原亚洲av无码app| 国产aⅴ激情无码久久| A级毛片无码久久精品免费| 久久九九兔免费精品6| 亚洲中文字幕无码久久2017| 精品久久久久久国产| 日韩精品久久无码人妻中文字幕| 亚洲精品无码久久久久| 久久久久久久久无码精品亚洲日韩| 婷婷久久香蕉五月综合加勒比 |