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

Đề tài: Vấn đề về con trỏ trong thừa kế ?

  1. #1
    Ngày gia nhập
    12 2008
    Bài viết
    1

    Smile Vấn đề về con trỏ trong thừa kế ?

    Bà con cho em hỏi vấn đề này với. Giả sử em có 2 lớp base và derived (kế thừa từ lớp base). Trong main em khai báo như sau


    Code:
    void main()
    {
    derived de[10];
    base *p;
    p = de; // địa chỉ bắt đầu của mảng đối tượng de
    p++; // tại sao sau câu lệnh này p trỏ tới 1 đối tượng thuộc lớp base mà không phải là 1 đối tượng thuộc lớp derived ?
    
    }

  2. #2
    No Avatar
    ngocbig Khách

    Bạn thử lại xem.

    Code:
    #include <iostream>
    
    class Base
    {
    public:
    	virtual void Report()
    	{
    		std::cout<<"I'm the base.\n";
    	}
    };
    class Derived:public Base
    {
    public:
    	void Report()
    	{
    		std::cout<<"I'm the derived.\n";
    	}
    };
    
    int main()
    {
    	Derived d[10];
    	Base* p=d;
    	p++;
    	p->Report();	//I'm the derived.
    }

  3. #3
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Java Code:
    1. p++;
    Cái này tương đương với p = p + sizeof( Base ). Cậu hỏi tại sao cho những cái bắt buộc thì tui cũng pótay vì trong C/C++ nó quan niệm như vậy. Nó không thể hiểu khác hơn được. Cho nên nó không thể trỏ tới đúng cái cậu cần được. Vì giả nếu có 3 thằng d trong mãng như sau( khoảng cách tới 1 thằng là 4 bytes.
    Code:
    [ d ]--- 4 ---[ d ]--- 4 ---[ d ]
    3 thằng d cách nhau 4 bytes, trong khi sizeof( Base ) = 2;
    thì câu lệnh : p++ sẽ dẫn tới p trỏ tới 1/2 x 4 = 2 bytes mà vùng nhớ này sẽ chẳng có gì hết và điều này sẽ dẫn tới :
    1. "segmentation fault" bên Linux.
    2. Hoặc "access violation - bên Window.

    Code của ngocbig chạy được là vì trong trường hợp đó sizeof( Base ) == sizeof( Derived ). Nếu 2 thằng này khác size nhau( thường thì lớp kế thừa và lớp cha chắc chắn là khác size nhau ) thì chắc chắn nó sẽ crash tại run-time.

  4. #4
    No Avatar
    ngocbig Khách

    tại sao sau câu lệnh này p trỏ tới 1 đối tượng thuộc lớp base mà không phải là 1 đối tượng thuộc lớp derived ?
    Chủ topic đang thắc mắc về vấn đề này. Do đó ví dụ của mình đưa ra chỉ để thấy rằng p++ thực chất chính là một object kiểu Derived. Còn vấn đề Mr. rox_rook lại liên quan tới chủ đề hoàn toàn khác. Tất nhiên là khi code trong real world thì không nên gán như thế (the most dangerous thing in c/c++ code! I think so.). Anyway, thanks for your Supplement! Mr rox_rook

  5. #5
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Thực ra tui hiểu ý của chủ topic, nhưng có điều cậu ta hiểu sai vấn đề khi cố dùng con trỏ của class Base trong trường hợp này.
    - Thứ 1 Base class pointer chỉ dùng đúng khi implement polymorphism, tức là có nhiều class kế thừa và dùng con trỏ Base class sẽ cực kì flexible trong trường hợp đó.
    - Nhưng nếu muốn dùng ++ cho Base class pointer thì đây là ý tưởng sai, bất kì 1 loại container nào( vector<>, list<>, deque<> đều có thể dùng iterator và có thể dùng toán tử ++ và -- ).
    Ví dụ :
    PHP Code:
    1. #include <iostream>
    2. #include <vector>
    3.  
    4. class Base {
    5. public:
    6.     virtual void Report() const = 0;
    7. };
    8.  
    9. class Derived_0 : public Base {
    10. public:
    11.     void Report() const {
    12.         std::cout<< "I'm the derived 0.\n";
    13.     }
    14. };
    15.  
    16. class Derived_1 : public Base {
    17. public :
    18.     void Report() const {
    19.         std::cout<< "I'm the derived 1.\n";
    20.     }
    21. };
    22.  
    23. int main()
    24. {
    25.     /*
    26.         Case 1
    27.         ...*/
    28.     std::vector< Base* > container;
    29.  
    30.     container.push_back( new Derived_0() );
    31.     container.push_back( new Derived_1() );
    32.  
    33.     container[ 0 ]->Report();
    34.     container[ 1 ]->Report();
    35.  
    36.     std::cout << std::endl << std::endl;
    37.     for( int o = 0; o < container.size(); ++o ) {
    38.         delete container[ o ];
    39.     }
    40.  
    41.     /*
    42.         Case 2
    43.         ...*/
    44.     std::vector< Derived_0 > derived_0_container( 10 );
    45.     for(
    46.         std::vector< Derived_0 >::const_iterator
    47.             b = derived_0_container.begin(),
    48.             e = derived_0_container.end();
    49.             b != e; ++b
    50.     )  {
    51.         b->Report();
    52.     }
    53.  
    54.     return 0;
    55. }

  6. #6
    No Avatar
    ngocbig Khách

    Mặc định Vấn đề về con trỏ trong thừa kế ?

    Yeah! Tôi đồng ý với bác về các ý bổ sung nhưng chủ topic không hỏi đến vấn đề mà bác đang minh họa. Tất nhiên là trong mọi trường hợp nếu sử dụng đc STL thì ta nên dùng. Trong trường hợp bắt buộc thì mới dùng đến các thao tác trên pointer. Chưa chắc người làm thế là ngừoi ta đã dùng sai. Giả sử chủ topic muốn "thử nghiên cứu" thêm về vấn đề đó thì sao?

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