Announcement

Collapse
No announcement yet.

Thắc mắc kế thừa trong C++

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

  • [C++] Thắc mắc kế thừa trong C++

    a/e ai giải thích được tại sao trong hàm main, đối tượng a gọi hàm Dislay() của lớp B mà không phải của lớp A?
    Code:
    #include<iostream>
    #include<conio.h>
    
    using namespace std;
    
    class A
    {
    public:
    	void Dislay(){ cout<<"A"<<endl;}
    };
    
    class B: virtual public A
    {
    public:
    	void Dislay(){ cout<<"B"<<endl;}
    };
    
    class C: virtual public A {};
    
    class D: public B, public C {};
    
    void main()
    {
    	D a;
    	a.Dislay();
    	getch();
    }
    Last edited by 11520327; 23-12-2012, 10:42.

  • #2
    Bỏ "C++ multiple inheritance function resolution" vào google tôi ra được trang này http://stackoverflow.com/questions/3...ion-order-in-c

    Comment


    • #3
      thứ tự xét hàm của chương trình:
      -đầu tiên kiểm tra trong lớp dẫn xuất (lớp D) xem có hàm Display ko,
      -vì trong lớp D ko có hàm Display nên tiếp tục kiểm tra lớp cớ sở có quan hệ gần nhất với D, tức là B và C
      nếu cả B và C đều ko có thì mới tới lớp A. còn nếu cả trong B và C đều có hàm Display thì chương trình lỗi

      Comment


      • #4
        đối tượng thuộc class con sẽ xét dần các phương thức từ nó -> lớp cha gần nhất. Và cứ thế theo một trình tự cho đến khi gặp lớp cha của tất cả.
        Top Best Online - The Best Products Review Website

        Comment


        • #5
          #3 và #4 trả lời rất ngắn gọn trong khi tìm hiểu link của #2 thì viết rất dài và rất... khó nuốt. điều này làm mình liên tưởng liệu câu trả lời có thật sự ngắn gọn đơn giản như #3, #4 hay không?

          Comment


          • #6
            Originally posted by 11520327 View Post
            #3 và #4 trả lời rất ngắn gọn trong khi tìm hiểu link của #2 thì viết rất dài và rất... khó nuốt. điều này làm mình liên tưởng liệu câu trả lời có thật sự ngắn gọn đơn giản như #3, #4 hay không?
            Muốn biết có thật vậy hay không thì em đọc hết cả #2, #3 và #4 đi.

            Comment


            • #7
              Theo mình nghĩ thì vì nó ko có phương thức Display() nên nó sẽ gọi phương thức Display() của lớp cha gần nhất là B:: Display() ( A:: Display() -> B:: Display() ), nếu C cũng override phương thức Display thì nó sẽ bị lỗi vì ko biết gọi B:: Display() hay C:: Display()
              btw, link #2 nói về kế thừa phương thức ảo, hok liên quan đến câu hỏi. Trong link đó cái post đầu tiên người ta nói thuật toán tổng quát để chọn phương thức ảo cần gọi, trình dịch thường dùng vptr với vtable đơn giản hơn nhiều vì nó chả cần biết và cũng chả cần chọn gì hết mà chỉ cần gọi đúng phương thức ảo trong vtable thôi.

              Edit: Mấy vấn đề về đa kế thừa này có nhiều vấn đề phức tạp, khó kiểm soát nên mấy ngôn ngữ cấp cao hơn như c# hay java đã bỏ lun phần đa kế thừa và thay vào đó = "đa giao diện" :smile:
              Thật sự mình thấy trong thực tế cũng hiếm có việc đa kế thừa, thường thì nó chỉ kế thừa từ 1 cái gì đó chính và phát triển thêm :embarrassed:...nên tốt nhất không nên dùng nếu không thật sự cần thiết :nosebleed:
              Last edited by 11520051; 25-12-2012, 14:17.

              Comment


              • #8
                Originally posted by 11520051 View Post
                Theo mình nghĩ thì vì nó ko có phương thức Display() nên nó sẽ gọi phương thức Display() của lớp cha gần nhất là B:: Display() ( A:: Display() -> B:: Display() ), nếu C cũng override phương thức Display thì nó sẽ bị lỗi vì ko biết gọi B:: Display() hay C:: Display()
                btw, link #2 nói về kế thừa phương thức ảo, hok liên quan đến câu hỏi. Trong link đó cái post đầu tiên người ta nói thuật toán tổng quát để chọn phương thức ảo cần gọi, trình dịch thường dùng vptr với vtable đơn giản hơn nhiều vì nó chả cần biết và cũng chả cần chọn gì hết mà chỉ cần gọi đúng phương thức ảo trong vtable thôi.
                Chỗ nào trong link dẫn ra ở #2 ghi là nó chỉ nói về kế thừa với phương thức ảo đâu em? Cái vtable với vptr đó là lập trình viên chỉ định hay do trình biên dịch tạo ra? Nếu trình biên dịch tạo ra nó nó phải có thuật toán để làm việc đó. Nếu các bạn muốn truy đến tận cùng cách trình biên dịch hoạt động thì C++ chưa bao giờ là một ngôn ngữ đơn giản.

                Comment


                • #9
                  Originally posted by truonganpn View Post
                  Chỗ nào trong link dẫn ra ở #2 ghi là nó chỉ nói về kế thừa với phương thức ảo đâu em? Cái vtable với vptr đó là lập trình viên chỉ định hay do trình biên dịch tạo ra? Nếu trình biên dịch tạo ra nó nó phải có thuật toán để làm việc đó. Nếu các bạn muốn truy đến tận cùng cách trình biên dịch hoạt động thì C++ chưa bao giờ là một ngôn ngữ đơn giản.
                  Sr thầy em chưa đọc kĩ cái link của thầy @.@,
                  Theo em biết thì vtable của lớp nào thì chứa những con trỏ hàm trỏ tới các phương thức ảo của lớp đó ( kể cả phương thức ảo của base nếu chưa đc override ) nên việc tạo ra vtable khá đơn giản chỉ như khởi tạo bình thường, mỗi đối tượng chỉ cần khởi tạo thêm 1 vptr trỏ tới vtable nữa là có thể truy xuất đến phương thức ảo cần gọi. @.@
                  Nên em nghĩ việc tạo ra vtable với vptr hok cần đến "thuật toán"

                  Nếu em có gì sai sót mong thầy thông cảm @.@
                  Last edited by 11520051; 25-12-2012, 10:38.

                  Comment

                  LHQC

                  Collapse
                  Working...
                  X