Từ 1 tới 2 trên tổng số 2 kết quả

Đề tài: Diamond Prolem trong C++

  1. #1
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,006

    Mặc định Diamond Prolem trong C++

    Vấn đề là gì?
    Trong lập trình hướng đối tượng với đa kế thừa, diamond problem là một vấn đề khá nổi tiếng khi mà : Có 2 class B và C kế thừa từ A, Class D kế thừa từ A và B. Khi gọi phương thức của A (không được override lại trong D) thì sẽ gọi tới hàm nào?




    ví dụ cơ bản 1 :
    C++ Code:
    1. #include "iostream"
    2. using namespace std;
    3.  
    4.  
    5.  
    6. class A
    7. {
    8. private:
    9.     int x;
    10. public:
    11.     int GetX(void)
    12.     {
    13.         return x;
    14.     }
    15.    
    16. };
    17.  
    18. class B:public A
    19. {
    20. };
    21. class C:public A
    22. {
    23. };
    24. class D:public B,public C
    25. {
    26.    
    27. };
    28.  
    29. void main(void)
    30. {
    31.     D x;
    32.     x.GetX(); ///////////<<<loi xuat hien tại dòng này
    33. }



    ví dụ cơ bản 2 :
    C++ Code:
    1. #include "iostream"
    2. using namespace std;
    3.  
    4.  
    5.  
    6. class A
    7. {
    8. private:
    9.     int x;
    10. public:
    11.     int GetX(void)
    12.     {
    13.         return x;
    14.     }
    15.    
    16. };
    17.  
    18. class B:public A
    19. {
    20. public:
    21.     int GetX(void)
    22.     {
    23.         return 2;
    24.     }
    25. };
    26. class C:public A
    27. {
    28. public:
    29.     int GetX(void)
    30.     {
    31.         return 3;
    32.     }
    33. };
    34. class D:public B,public C
    35. {
    36.    
    37. };
    38.  
    39. void main(void)
    40. {
    41.     D x;
    42.     x.GetX(); ///////////// sẽ gọi đến thằng nào ??????????????????
    43.    
    44. }



    Và đâu là giải pháp?
    Giải pháp cho cho ví dụ 1 :
    C++ Code:
    1. #include "iostream"
    2. using namespace std;
    3.  
    4.  
    5.  
    6. class A
    7. {
    8. private:
    9.     int x;
    10. public:
    11.     int GetX(void)
    12.     {
    13.         return x;
    14.     }
    15.    
    16. };
    17.  
    18. class B:virtual public A
    19. {
    20. };
    21. class C:virtual public A
    22. {
    23. };
    24. class D:public B,public C
    25. {
    26.    
    27. };
    28.  
    29. void main(void)
    30. {
    31.     D x;
    32.     x.GetX(); //ngon lành cành đào
    33.    
    34. }


    giải pháp cho case 2 :
    C++ Code:
    1. #include "iostream"
    2. using namespace std;
    3.  
    4.  
    5.  
    6. class A
    7. {
    8. private:
    9.     int x;
    10. public:
    11.     int GetX(void)
    12.     {
    13.         cout<<"a"<<endl;
    14.         return x;
    15.     }
    16.    
    17. };
    18.  
    19. class B:public A
    20. {
    21. public:
    22.     int GetX(void)
    23.     {
    24.         cout<<"b"<<endl;
    25.         return 2;
    26.     }
    27. };
    28. class C:public A
    29. {
    30. public:
    31.     int GetX(void)
    32.     {
    33.         cout<<"c"<<endl;
    34.         return 3;
    35.     }
    36. };
    37. class D:public B,public C
    38. {
    39.    
    40. };
    41.  
    42. void main(void)
    43. {
    44.     D x;
    45.     B* p;
    46.     x.B::GetX(); //gọi B
    47.     x.C::GetX(); // gọi C
    48.     p=&x;
    49.     p->A::GetX(); // gọi A
    50. }

    Bài viết khá đơn giản, mong được các bạn góp ý thêm
    thx các bạn.
    Attached Thumbnails Attached Thumbnails Diamondinheritance.png  
    ^_,^

    Tổng hợp các câu chuyện hài hước vui nhộn, sử dụng Speech Synthesis để đọc : https://www.youtube.com/channel/UCLk...Tjrg/playlists


    Bùi Tấn Quang

  2. #2
    Ngày gia nhập
    12 2008
    Nơi ở
    Hà Nội
    Bài viết
    374

    Thumbs down Vấn đề Diamond và class cơ sở virtual

    Vấn đề Diamond


    Derived_1 vaf Derived_2 cùng thừa kế Base. Derived_3 thừa kế từ Derived_1 và Derived_2, khi đó, sẽ tồn tại 2 thực thể của Base trong Derived_3. Hơn nữa, nếu trong Derived_1 và Derived_2 có 2 thành viên cùng tên cho phép thừa kế, thì ở Derived_3, khi truy cập thành viên đó, thì thành viên của Derived_1 hay Derived_2 được truy cập ?


    Visual C++ Code:
    1.  #include  <iostream>
    2.  
    3.  class  Base
    4.  {
    5.  public:
    6.         Base(int  nValue)
    7.         {
    8.                m_nValue =  nValue;
    9.                std::cout<<"Base :  "<<nValue<<std::endl;
    10.         }
    11.  
    12.  private:
    13.         int  m_nValue;
    14.  };
    15.  
    16.  class  Derived_1 : public Base
    17.  {
    18.  public:
    19.         Derived_1(int nValue)
    20.                 :Base(nValue)
    21.         {
    22.                std::cout<<"Derived 1 :  "<<nValue<<std::endl;
    23.         }
    24.  };
    25.  
    26.  class  Derived_2 : public Base
    27.  {
    28.  public:
    29.         Derived_2(int nValue)
    30.                 :Base(nValue)
    31.         {
    32.                std::cout<<"Derived 2 :  "<<nValue<<std::endl;
    33.         }
    34.  };
    35.  
    36.  class  Derived_3 : public Derived_1 , public Derived_2
    37.  {
    38.  public:
    39.         Derived_3(int nValue)
    40.                :Derived_1(nValue),  Derived_2(nValue)
    41.         {
    42.                std::cout<<"Derived 3 :  "<<nValue<<std::endl;
    43.         }
    44.  };
    45.  
    46.  
    47.  int  main()
    48.  {
    49.         using  namespace std;
    50.        
    51.         Derived_3  derived_3(10);
    52.        
    53.         /*
    54.          *  Output
    55.          *
    56.          Base : 10
    57.          Derived 1 : 10
    58.          Base : 10
    59.          Derived 2 : 10
    60.          Derived 3 : 10
    61.        
    62.         */
    63.  
    64.         cin.get();
    65.         return  0;
    66.  }


    Class cơ sở virtual


    Trong ví dụ trên, để Deriver_3 chỉ chứa 1 thực thể của Base, ta sử dụng class cơ sở virtual.


    Visual C++ Code:
    1.  #include  <iostream>
    2.  
    3.  class  Base
    4.  {
    5.  public:
    6.         Base(int  nValue)
    7.         {
    8.                m_nValue =  nValue;
    9.                std::cout<<"Base :  "<<nValue<<std::endl;
    10.         }
    11.  
    12.  private:
    13.         int  m_nValue;
    14.  };
    15.  
    16.  class  Derived_1 : virtual public Base
    17.  {
    18.  public:
    19.         Derived_1(int nValue)
    20.                 :Base(nValue)
    21.         {
    22.                std::cout<<"Derived 1 :  "<<nValue<<std::endl;
    23.         }
    24.  };
    25.  
    26.  class  Derived_2 : virtual public Base
    27.  {
    28.  public:
    29.         Derived_2(int nValue)
    30.                 :Base(nValue)
    31.         {
    32.                std::cout<<"Derived 2 :  "<<nValue<<std::endl;
    33.         }
    34.  };
    35.  
    36.  class  Derived_3 : public Derived_1 , public Derived_2
    37.  {
    38.  public:
    39.         Derived_3(int nValue)
    40.                :Derived_1(nValue),  Derived_2(nValue), Base(nValue)
    41.         {
    42.                std::cout<<"Derived 3 :  "<<nValue<<std::endl;
    43.         }
    44.  };
    45.  
    46.  
    47.  int  main()
    48.  {
    49.         using  namespace std;
    50.        
    51.         Derived_3  derived_3(10);
    52.        
    53.         /*
    54.          *  Output
    55.          *
    56.          Base : 10
    57.          Derived 1 : 10
    58.          Derived 2 : 10
    59.          Derived 3 : 10
    60.        
    61.         */
    62.  
    63.         cin.get();
    64.         return  0;
    65.  }





    Có 3 lưu ý :

    • Class cơ sở virtual sẽ được tạo trước các class cơ sở non-virtual, điều này đảm bảo lớp cơ sở sẽ được tạo trước khi các lớp thừa kế nó được tạo.
    • Chú ý rằng, Derived_1 và Derived_2 vẫn gọi hàm tạo của Base. Tuy nhiên, khi tạo thực thể của Derived_3, những cuộc gọi đó sẽ bị bỏ qua, và Derived_3 sẽ chịu trách nhiệm gọi hàm tạo của Base. Nếu ta tạo thực thể của Derived_1 hoặc Derived_2, thì từ khóa virtual sẽ bị bỏ qua, và luật thừa kế được áp dụng bình thường.
    • Trong trường hợp trên, Derived_3 sẽ chịu trách nhiệm tạo thực thể của Base. Kể cả Derived_3 chỉ thừa kế từ Derived_1, mà Derived_1 có class cơ sở virtual là Base, thì Derived_3 vẫn phải chịu trách nhiệm tạo thực thể của Base.

Các đề tài tương tự

  1. Liền kề diamond park, biệt thự diamond park, căn góc, vị trí đẹp, giá ưu đãi
    Gửi bởi ephat_tt86 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 29-11-2011, 02:05 PM
  2. Diamond Park Mê Linh, biệt thự diamond, liền kề diamond Cần bán
    Gửi bởi ephat_tt86 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 04-11-2011, 01:47 PM
  3. ~Diamond Park Mê Linh,biệt thự diamond,liền kề diamond Cần bán
    Gửi bởi ephat_tt86 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 1
    Bài viết cuối: 29-10-2011, 08:24 AM
  4. Liền kề Diamond Park, biệt thự diamond park-sanduan.info
    Gửi bởi ephat_tt86 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 26-10-2011, 10:22 AM
  5. Prolem: Input: Số dạng string, Output: tổng và tích
    Gửi bởi dongsihoanglan trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 01-05-2011, 01:36 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn