Announcement

Collapse
No announcement yet.

Vẫn đề về Virtual base class

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [C++] Vẫn đề về Virtual base class

    Giả sử mình định nghĩa class A rồi class B và C kế thừa A, sau đó mình đưa cho người khác phát triển tiếp, vì một lý do nào đó mà người đó không muốn sửa code mình đưa cho họ hay vì lý do "bản quyền" mình không cho người ta đọc hay sửa phần code định nghĩa A,B và C mà chỉ cho họ phát triển tiếp thông qua kế thừa 3 class đó.
    Nhưng lúc kế thừa B và C thì lại có lại gặp vấn đề "diamond problem", nó sẽ gây ra lỗi "mơ hồ" vì trong B cũng có thành phần A, trong C cũng có thành phần A, 2 cái này trùng lắp nhau.
    Trong c++ để giải quyết "diamond problem" thì mình để B và C kế thừa từ lớp cơ sở ảo A nhưng lúc ban đầu thì mình không dự tính phát triển thêm 1 class kế thừa từ B và C nên không sử dụng "Kế thừa lớp cơ sở ảo"
    Zậy có bạn nào có giải pháp cho vấn đề này ko? :funny:

    Mình thấy cái phần kế thừa lớp cơ sở ảo phải do phần định nghĩa của D quyết định chứ lúc mình viết class B và C chưa chắc mình đã dự tính viết thêm 1 class kế thừa từ lớp B và C, giờ mún làm vậy phải quay lại sửa phần định nghĩa của B và C... udency:
    Last edited by 11520051; 27-12-2012, 17:54.

  • #2
    Originally posted by 11520051 View Post
    Giả sử mình định nghĩa class A rồi class B và C kế thừa A, sau đó mình đưa cho người khác phát triển tiếp, vì một lý do nào đó mà người đó không muốn sửa code mình đưa cho họ hay vì lý do "bản quyền" mình không cho người ta đọc hay sửa phần code định nghĩa A,B và C mà chỉ cho họ phát triển tiếp thông qua kế thừa 3 class đó.
    Nhưng lúc kế thừa B và C thì lại có lại gặp vấn đề "diamond problem", nó sẽ gây ra lỗi "mơ hồ" vì trong B cũng có thành phần A, trong C cũng có thành phần A, 2 cái này trùng lắp nhau.
    Trong c++ để giải quyết "diamond problem" thì mình để B và C kế thừa từ lớp cơ sở ảo A nhưng lúc ban đầu thì mình không dự tính phát triển thêm 1 class kế thừa từ B và C nên không sử dụng "Kế thừa lớp cơ sở ảo"
    Zậy có bạn nào có giải pháp cho vấn đề này ko? :funny:

    Mình thấy cái phần kế thừa lớp cơ sở ảo phải do phần định nghĩa của D quyết định chứ lúc mình viết class B và C chưa chắc mình đã dự tính viết thêm 1 class kế thừa từ lớp B và C, giờ mún làm vậy phải quay lại sửa phần định nghĩa của B và C... udency:
    Theo như bạn nói thì B ko kế thừa từ A , chỉ C kế thừa từ A , thì lúc gọi hàm cũng đâu có lỗi :aboom:
    Nếu ko sử dụng virtual base class thì lúc gọi tới hàm , bạn chỉ rõ ra nó thuộc lớp nào luôn .
    Ví dụ tạo đối tượng a thuộc lớp D , bạn chỉ rõ ra hàm cần gọi thuộc hẳn lớp nào luôn ( nếu có override ) như là a.C::function() hay a.D::function()
    Không biết mình có nói đúng ý bạn không nhỉ ? :nosebleed:
    Last edited by 11520235; 27-12-2012, 20:18.

    Comment


    • #3
      Originally posted by 11520235 View Post
      Theo như bạn nói thì B ko kế thừa từ A , chỉ C kế thừa từ A , thì lúc gọi hàm cũng đâu có lỗi :aboom:
      Nếu ko sử dụng virtual base class thì lúc gọi tới hàm , bạn chỉ rõ ra nó thuộc lớp nào luôn .
      Ví dụ tạo đối tượng a thuộc lớp D , bạn chỉ rõ ra hàm cần gọi thuộc hẳn lớp nào luôn ( nếu có override ) như là a.C::function() hay a.D::function()
      Không biết mình có nói đúng ý bạn không nhỉ ? :nosebleed:
      Hok đúng =]]
      Nếu bạn có lớp B và C kế thừa từ A, rồi định nghĩa lớp D kế thừa B và C thì trong D sẽ có 2 phần A trùng nhau nên sẽ gây ra lỗi rồi chứ chưa gần gọi tới hàm gì đâu,
      Hình như ý của bạn là B và C định nghĩa cùng tên hàm và D gọi hàm đó -> báo lỗi mơ hồ. Nhưng hok phải ý mình hỏi =]]

      Comment


      • #4
        Originally posted by 11520051 View Post
        Hok đúng =]]
        Nếu bạn có lớp B và C kế thừa từ A, rồi định nghĩa lớp D kế thừa B và C thì trong D sẽ có 2 phần A trùng nhau nên sẽ gây ra lỗi rồi chứ chưa gần gọi tới hàm gì đâu,
        Hình như ý của bạn là B và C định nghĩa cùng tên hàm và D gọi hàm đó -> báo lỗi mơ hồ. Nhưng hok phải ý mình hỏi =]]
        Ở trên bạn nói B đâu kế thừa từ A đâu , mình đọc bài của bạn sao mình nói vậy thôi :nosebleed:
        Còn đối với lớp cơ sở A bị override bởi 2 lớp B và C , còn D là lớp dẩn xuất từ B và C thì khi gọi sẽ gặp diamond problem rồi , theo cách tụi mình học hiện tại thì cho A là lớp cơ sở trừu tượng ( là trong hàm phải có hàm ảo thuần túy ) rồi sau đó khai báo trỏ lớp A tham chiếu đến những đối tượng thuộc 2 lớp dẫn xuất là B và C là sẽ gọi được hàm override của 2 lớp đó , lúc này sẽ không cần phát triển thêm D .:sunglasses:
        Code:
        A *x,*y;
        B a; x=&a; x-> <function>;
        C b; y=&b; y-> <function>;
        Không biết mình nói đúng ý bạn chưa nhỉ ? :shy:
        Last edited by 11520235; 27-12-2012, 22:57.

        Comment


        • #5
          "B và C kế thừa từ A"
          Dấu và ở đây ưu tiên cao nhất nha bạn =]]

          Comment


          • #6
            Originally posted by 11520051 View Post
            "B và C kế thừa từ A"
            Dấu và ở đây ưu tiên cao nhất nha bạn =]]
            Đọc lộn " Class A rồi Class B " , " và Class C " =))

            Comment


            • #7
              Originally posted by 11520235 View Post
              Ở trên bạn nói B đâu kế thừa từ A đâu , mình đọc bài của bạn sao mình nói vậy thôi :nosebleed:
              Còn đối với lớp cơ sở A bị override bởi 2 lớp B và C , còn D là lớp dẩn xuất từ B và C thì khi gọi sẽ gặp diamond problem rồi , theo cách tụi mình học hiện tại thì cho A là lớp cơ sở trừu tượng ( là trong hàm phải có hàm ảo thuần túy ) rồi sau đó khai báo trỏ lớp A tham chiếu đến những đối tượng thuộc 2 lớp dẫn xuất là B và C là sẽ gọi được hàm override của 2 lớp đó , lúc này sẽ không cần phát triển thêm D .:sunglasses:
              Code:
              A *x,*y;
              B a; x=&a; x-> <function>;
              C b; y=&b; y-> <function>;
              Không biết mình nói đúng ý bạn chưa nhỉ ? :shy:
              Ở đây cái mà bạn đang nói là về tính đa hình với lớp trừu tượng ( abstract class)

              Ý mình là nếu muốn phát triển thêm 1 lớp kế thừa từ B và C mà B và C ko "kế thừa lớp cở sở ảo" A thì không thể nào được vì lúc đó trong B sẽ xuất hiện 2 thành phần A -> gây ra lỗi
              còn mình ko hiểu ý "ko cần phát triển thêm" của bạn? :doubt:
              chắc bạn đang nhầm cái virtual trong "virtual base class" với virtual đứng trước tên phương thức là 2 cái khác nhau 1 trời 1 vực, mà chắc bạn đang nhầm giữa lớp cơ sở ảo và lớp trừu tượng :nosebleed:

              Comment


              • #8
                Originally posted by 11520051 View Post
                Ở đây cái mà bạn đang nói là về tính đa hình với lớp trừu tượng ( abstract class)

                Ý mình là nếu muốn phát triển thêm 1 lớp kế thừa từ B và C mà B và C ko "kế thừa lớp cở sở ảo" A thì không thể nào được vì lúc đó trong B sẽ xuất hiện 2 thành phần A -> gây ra lỗi
                còn mình ko hiểu ý "ko cần phát triển thêm" của bạn? :doubt:
                chắc bạn đang nhầm cái virtual trong "virtual base class" với virtual đứng trước tên phương thức là 2 cái khác nhau 1 trời 1 vực, mà chắc bạn đang nhầm giữa lớp cơ sở ảo và lớp trừu tượng :nosebleed:
                Thì giải pháp của mình là xài abstract base class đó :nose:
                Về " virtual base class " thì sẽ có lỗi ambigious khi 1 đối tượng D (kế thừa từ B và C ) gọi 1 phương thức override từ trên ra , vì gọi hàm đã override theo lớp cơ sở ảo , nó sẽ xét từ hàm cơ sở gần nhất của nó ra , khi cơ sở gần nhất của nó có >=2 thì sẽ lỗi , vấn đề này đã được nói ở đây nè bạn http://forum.uit.edu.vn/threads/2763...-thua-trong-C- :boss:
                Còn cách khắc phục thì như mình nói hôm nãy , muốn gọi hàm bị override của lớp nào thì gọi hẳn nó ra , còn gọi chung chung mà ko có lỗi ambigious theo những cái đang học thì ...... không biết :sogood:

                Comment


                • #9
                  Theo mình nghĩ thì k có cách nào đâu. Người A muốn giữ y nguyên bản quyền, không muốn cho kế thừa phát triển thì người B có muốn làm gì đi nữa cũng không thể. Và có thể vì điều này mà C++ đã không cho giải quyết 1 cách tuỳ tiện. .
                  Top Best Online - The Best Products Review Website

                  Comment


                  • #10
                    Vì cái này mà hầu hết các ngôn ngữ OOP đẹp đẹp sau này đều chỉ cho một lớp kế thừa từ một lớp khác (đơn kế thừa) ^_^. Mà theo như bạn nói thì vấn đề của bạn là do bạn đã bị sai ngay từ bước design khi bỏ qua việc virtual những cái trong A có thể gây ra diamond problem. Để giải quyết trường hợp này thì mình nghĩ bạn không nên cho D kế thừa từ B và C mà hãy viết D như là 1 lớp adapter có các phương thức mở rộng riêng, trong đó sẽ gọi tới phương thức của B và C tương ứng
                    Chưa....

                    Comment


                    • #11
                      Originally posted by 08520522 View Post
                      Vì cái này mà hầu hết các ngôn ngữ OOP đẹp đẹp sau này đều chỉ cho một lớp kế thừa từ một lớp khác (đơn kế thừa) ^_^. Mà theo như bạn nói thì vấn đề của bạn là do bạn đã bị sai ngay từ bước design khi bỏ qua việc virtual những cái trong A có thể gây ra diamond problem. Để giải quyết trường hợp này thì mình nghĩ bạn không nên cho D kế thừa từ B và C mà hãy viết D như là 1 lớp adapter có các phương thức mở rộng riêng, trong đó sẽ gọi tới phương thức của B và C tương ứng
                      Em hok hiểu ý anh là B và C kế thừa từ lớp cơ sở ảo A hay cho mấy thành phần của A thành virtual?
                      Nếu để cho B và C kế thừa từ lớp cơ sở ảo A thì không hợp lý vì ngay từ đầu ko dự định xây dựng 1 lớp kế thừa từ cả B và C
                      Còn nếu virtual các phương thức trong A thì còn các biến thì sao?

                      Giả sử e viết D như 1 lớp adapter, nhưng có một hàm nào đó cần truy xuất đến thành phần biến của A trong D thì sao? Dù kiểu gì thì kiểu nó vẫn gây ra lỗi mơ hồ, vẫn đề ở đây ko nằm ở hàm vì hàm có thể ghi đè được, vấn đề em nói ở đây nằm ở biến cơ.
                      Last edited by 11520051; 01-01-2013, 09:34.

                      Comment


                      • #12

                        lười ghi lại quá @@
                        ở trên trong link đó, ngay cái giải pháp cho case 2: cách gọi đến các phương thức như thế ko biết là đã giải quyết vấn đề của bạn chưa. Ý bạn là không thay đổi 3 class A,B,C nhưng vẫn giải quyết dc diamond problem ?

                        Comment

                        LHQC

                        Collapse
                        Working...
                        X