Announcement

Collapse
No announcement yet.

Đa hình: vấn đề khi truy xuất hàm riêng của lớp con

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

  • [C++] Đa hình: vấn đề khi truy xuất hàm riêng của lớp con

    Em có đoạn code sau (trích từ một đề thi thực hành)
    Code:
    void main()
    {
            Teacher t; 
    	t.Nhap();
    	Student s; 
    	s.Nhap(); 
    
    	Person* p; 
    	p = &t; 
    	p->TinhLuong();  //báo lỗi
    	p->Xuat(); 
    	p = &s; 
    	p->TinhDTB(); 
    	p->Xuat();
    }
    3 lớp Person, Teacher, Student:
    Code:
    class Person
    {
    protected:
    	char *hoten;
    	long CMND;
    public:
    	virtual void Nhap();
    	virtual void Xuat();
    };
    
    class Teacher : public Person
    {
    private:
    	long LuongCB;
    	int HeSo;
    	long Luong;
    public:
    	void Nhap();
    	void Xuat();
    	void TinhLuong();
    };
    
    class Student : public Person
    {
    private:
    	float toan, tin, ********, DTB;
    public:
    	void Nhap();
    	void Xuat();
    	void TinhDTB();
    };
    trong đó, lớp Teacher và Student kế thừa từ lớp Person với từ khóa public
    Khi Ctrl+F5, máy báo lỗi ngay tại dòng "p->TinhLuong(); " trong hàm main (error 2039: 'TinhLuong' is not a member of 'Person')
    Vậy em cần sửa lại gì để chạy được mà không chỉnh sửa hàm main? Vì đề bài yêu cầu xây dựng các lớp để chạy được đoạn chương trình trên.
    13520747
    Nguyễn Trần Minh Tân
    Last edited by 13520747; 29-05-2014, 01:09.
    Đừng bán rẻ mình...
    Mà phải BÁN ĐÚNG GIÁ!!!

  • #2
    Originally posted by 13520747 View Post
    Khi Ctrl+F5, máy báo lỗi ngay tại dòng "p->TinhLuong(); " trong hàm main (error 2039: 'TinhLuong' is not a member of 'Person')
    Vậy em cần sửa lại gì để chạy được mà không chỉnh sửa hàm main? Vì đề bài yêu cầu xây dựng các lớp để chạy được đoạn chương trình trên.
    Nó báo lỗi là đúng rồi, p là con trỏ kểu Person mà kiểu person thì ko thể biết được phương thức TinhLuong của lớp kế thừa của nó.
    Muốn chạy thì cast down tức là chuyển con trỏ kiểu Person về kiểu Subclass của nó rồi sử dụng phương thức của subclass như bt.
    Xem thêm tại:
    http://stackoverflow.com/questions/2...lass-pointer-c

    Comment


    • #3
      Originally posted by 13520747 View Post
      trong đó, lớp Teacher và Student kế thừa từ lớp Person với từ khóa public
      Khi Ctrl+F5, máy báo lỗi ngay tại dòng "p->TinhLuong(); " trong hàm main (error 2039: 'TinhLuong' is not a member of 'Person')
      Vậy em cần sửa lại gì để chạy được mà không chỉnh sửa hàm main? Vì đề bài yêu cầu xây dựng các lớp để chạy được đoạn chương trình trên.
      Bài của bạn làm chính xác, chỉ gặp một vấn đề nhỏ ở "lời gọi phương thức ảo" (trong thừa kế và đa hình). "Lời gọi tới phương thức ảo từ một con trỏ chưa cho biết rõ phương thức nào (trong số các phướng thức ảo trùng tên của các lớp có quan hệ thừa kế) sẽ được gọi. Điều này phụ thuộc vào đối tượng cụ thể mà con trỏ đang trỏ tới: Con trỏ đang trỏ tới đối tượng của lớp nào thì phương thức của lớp đó sẽ được gọi."
      Bạn chỉ cần khai báo thêm dòng
      Code:
      virtual TinhLuong ()
      {
      }
      trong lớp Person là có thể chạy được.
      Ps: Nếu dòng TinhLuong() có lỗi thì chắc dòng TinhDTB() cũng phải báo lỗi?
      I don't know the secret to success, but the secret to failure is trying to please everyone

      Comment


      • #4
        Originally posted by tara95 View Post
        Bạn chỉ cần khai báo thêm dòng
        Code:
        virtual TinhLuong ()
        {
        }
        trong lớp Person là có thể chạy được.
        Ps: Nếu dòng TinhLuong() có lỗi thì chắc dòng TinhDTB() cũng phải báo lỗi?
        cảm ơn bạn, mình đã làm ok rồi
        nhưng mình có một thắc mắc: tại sao phải khai báo "virtual void TinhLuong(){}" trong lớp Person?
        ở đây do chỉ có 2 lớp con là Student và Teacher, và mỗi lớp con cũng chỉ có 1 hàm riêng
        Giả sử như lớp Person có khoảng 100 lớp con (SinhVien, GiaoVien, HocSinh, CongNhan, ...), và mỗi lớp con lại có vài hàm riêng như thế thì mình phải tạo bằng đó hàm virtual trong lớp Person??
        à quên nữa, mình cũng đã từng thêm hàm TinhLuong và TinhDTB vào lớp Person, nhưng không định nghĩa hàm ở trong khai báo lớp mà định nghĩa bên ngoài lớp như các hàm khác thì báo lỗi như hình :angry:
        Untitled.png
        Đừng bán rẻ mình...
        Mà phải BÁN ĐÚNG GIÁ!!!

        Comment


        • #5
          - Ý 1: Cứ theo định nghĩa mà làm thôi cậu.
          - Y 2: Cảm phiền cậu up hết project được không?
          I don't know the secret to success, but the secret to failure is trying to please everyone

          Comment


          • #6
            *Ý 1: theo yêu cầu đề bài này thì làm như thế là ok rồi
            nhưng mình thấy nó hơi sai về mặt tư tưởng thì phải. Theo mình biết thì "Đa hình: Là hiện tượng các đối tượng thuộc các lớp khác nhau có khả năng hiểu cùng một thông điệp theo các cách khác nhau."
            có nghĩa là các đối tượng thuộc các lớp dẫn xuất đều hiểu được "cùng một thông điệp" của lớp cơ sở, nhưng theo những cách khác nhau
            còn theo như trong bài thì lại khác, "Student" đâu có hiểu được thông điệp "TinhLuong", cũng như "Teacher" không hiểu được thông điệp "TinhDTB"
            Mình nghĩ những hàm đó cần được cài đặt như những hàm riêng của mỗi lớp chứ không phải là khai báo hàm ảo ở lớp cơ sở.
            Chắc là ép kiểu từ Person sang Student và Teacher như anh [MENTION=7531]09520074[/MENTION] nói ở trên

            *Ý 2: do mình quên tên lớp nên báo lỗi :waaaht:
            giờ nhìn cái hình mới thấy :3

            P/S: gửi bạn cái link đề bài
            https://docs.google.com/viewer?pid=e...hdt.pdfhttp://
            Đừng bán rẻ mình...
            Mà phải BÁN ĐÚNG GIÁ!!!

            Comment


            • #7
              ^
              sao bạn ko up cái project lên?
              nhìn code mới biết đc chứ bạn...
              u should run..

              Comment


              • #8
                đây là cái project của em
                Attached Files
                Đừng bán rẻ mình...
                Mà phải BÁN ĐÚNG GIÁ!!!

                Comment


                • #9
                  Originally posted by 13520747 View Post
                  đây là cái project của em
                  Mình thấy chạy ổn mà, chắc cậu sửa xong rồi.
                  P/s: Đề bài yêu cầu làm việc với file.
                  I don't know the secret to success, but the secret to failure is trying to please everyone

                  Comment


                  • #10
                    Originally posted by tara95 View Post
                    Mình thấy chạy ổn mà, chắc cậu sửa xong rồi.
                    P/s: Đề bài yêu cầu làm việc với file.
                    uhm mình sửa rồi
                    tại vì thầy thực hành giới hạn là không nhập xuất file nên mình không làm
                    Đừng bán rẻ mình...
                    Mà phải BÁN ĐÚNG GIÁ!!!

                    Comment


                    • #11
                      Code:
                      Person* p; 
                      	p = &t; 
                      	p->TinhLuong();  //báo lỗi
                      	p->Xuat(); 
                      	p = &s; 
                      	p->TinhDTB(); 
                      	p->Xuat();
                      do cái con trỏ *p nên nó mới gây ra cái sự rắc rồi này đó bạn. Nó ưu tiên gọi hàm của person trước, nên bắt buộc phải có mấy cái tinhluong voi tinhdtb trong class person( khai báo virtual). Dù mấy hàm đó ko làm gì cả nhưng nó thể hiện tính đa hình của HĐT @@.

                      Mà ai biết làm bài này nhập xuất file chỉ mình với, lỡ ra thi còn biết đường làm. Thanks!

                      Comment


                      • #12
                        Không biết đề bài cho tới đâu. Nếu chỉ cho ý tưởng thôi thì bạn sửa ép kiểu con trỏ Person sang sub-class của nó lại (như khi gặp một đám đông người thì bạn có thể gọi bất cứ ai là Người, nhưng ngược lại không thể gọi cả đám đông đó cụ thể là "Giáo Viên" được vì biết đầu còn có "Phụ Huynh" trong đó và đương nhiên không thể bắt một ai trong đó đi "dạy học" cho bạn được). Tư tưởng là vậy. Nếu cho hàm main để cài theo thì đề bài có chút vấn đề.

                        Originally posted by 13520747 View Post
                        cảm ơn bạn, mình đã làm ok rồi
                        nhưng mình có một thắc mắc: tại sao phải khai báo "virtual void TinhLuong(){}" trong lớp Person?
                        ở đây do chỉ có 2 lớp con là Student và Teacher, và mỗi lớp con cũng chỉ có 1 hàm riêng
                        Giả sử như lớp Person có khoảng 100 lớp con (SinhVien, GiaoVien, HocSinh, CongNhan, ...), và mỗi lớp con lại có vài hàm riêng như thế thì mình phải tạo bằng đó hàm virtual trong lớp Person??
                        [ATTACH=CONFIG]13045[/ATTACH]
                        Bạn thắc mắc rất hay, cái này không hiểu từ đầu thì sẽ nguy hiểm về sau, nhiều bạn muốn tìm cách giải quyết cho xong vấn đề chứ không muốn giải thích vấn đề. Đúng là cần có một giao diện của mỗi lớp để lớp giao tiếp bên ngoài, các sub-class sẽ kế thừa và phát huy nó theo ý của nó nhưng vẫn giữ giao diện đó để cho bên ngoài giao tiếp. Ví dụ ở đây, Người thì (hầu hết) ai cũng có hành động là "đi bộ". Tuy nhiên, Giáo Viên họ sẽ đi đứng khác với Sinh Viên như "lịch sự, chậm rãi, phong thái" hơn, còn sinh viên thì "hấp tấp, vội vàng"....
                        -p/s: Ở đây mình không code ví dụ cụ thể vì sẽ làm mất đi tính sáng tạo của mỗi người vì nó mang tính chủ quan nên nếu đề bài không cho hẳn cái hàm main thì với những gợi ý của mình hy vọng bạn có thể thực hiện nó thật đúng nghĩa "hướng đối tượng".

                        Comment


                        • #13
                          Thắc mắc của em hay. Mà anh cũng xin giải thích thêm tý.
                          Giả sử em có 1 danh sách các đối tượng là người. Thì để quản lý được danh sách đó em có thể tạo ra từng list riêng theo từng Object riêng để quản lý nhưng mà làm điều đó rất mất công và đồng thời lại dễ xảy ra sai sót.
                          Thay vì đó đa hình cho phép ta quản lý tất cả các đối tượng cùng kế thừa từ 1 lớp bằng cách dùng 1 list mà mỗi phần từ trong list là 1 pointer của lớp cha.
                          Khi thực hiện Update hoặc thao tác gì trên list đó thì em sẽ dễ dàng hơn. vì chỉ dùng 1 dòng for hoặc while là được.
                          Đây cũng là cách mà mình dùng để Update Object và GameState :sunglasses:
                          Originally posted by 13520747 View Post
                          cảm ơn bạn, mình đã làm ok rồi
                          nhưng mình có một thắc mắc: tại sao phải khai báo "virtual void TinhLuong(){}" trong lớp Person?
                          ở đây do chỉ có 2 lớp con là Student và Teacher, và mỗi lớp con cũng chỉ có 1 hàm riêng
                          Giả sử như lớp Person có khoảng 100 lớp con (SinhVien, GiaoVien, HocSinh, CongNhan, ...), và mỗi lớp con lại có vài hàm riêng như thế thì mình phải tạo bằng đó hàm virtual trong lớp Person??
                          à quên nữa, mình cũng đã từng thêm hàm TinhLuong và TinhDTB vào lớp Person, nhưng không định nghĩa hàm ở trong khai báo lớp mà định nghĩa bên ngoài lớp như các hàm khác thì báo lỗi như hình :angry:
                          [ATTACH=CONFIG]13045[/ATTACH]
                          -Trần Hữu Danh-
                          -GameUIT - SE-
                          ...Slowly... But Strongly...
                          clbgameuit.com F/clbgameuit

                          Comment


                          • #14
                            [MENTION=34862]13520045[/MENTION]: Cảm ơn bạn, cái này mình debug vài lần cũng đã thấy được vấn đề
                            mình chỉ nghĩ khai báo thêm vài cái hàm virtual mà chỉ xài được ở 1 hoặc 1 vài lớp con thì không đa hình lắm
                            à cái phần nhập xuất file dễ lắm bạn )
                            xài cái fstream là khỏe nhất, bạn có thể lên google tìm hiểu, không khó hiểu lắm đâu :beauty:
                            [MENTION=18851]12520054[/MENTION]: dạ cái này thì em biết )
                            em có cả code mẫu bài "Tính tiền lương" của cô Nguyệt Minh nữa cơ
                            [MENTION=7697]10520437[/MENTION]: Cảm ơn anh
                            cách đó em cũng có nghe tới nhưng chưa thật sự hiểu và biết làm :3
                            anh sửa lại cái hàm main theo cách đó giúp em được không anh?
                            Đừng bán rẻ mình...
                            Mà phải BÁN ĐÚNG GIÁ!!!

                            Comment

                            LHQC

                            Collapse
                            Working...
                            X