2010-10-01 41 views
35

Tôi luôn nghĩ đến việc phải sử dụng con trỏ cho đa hình. Sử dụng ví dụ kinh điển:Tham chiếu và con trỏ có liên quan đến đa hình không?

DrawEngine::render(Shape *shape) 
{ 
    shape->draw(); 
    shape->visible(true); 
} 

Và chuyển đến con trỏ tới các lớp có nguồn gốc khác nhau. Nó có hoạt động giống với tham chiếu không?

DrawEngine::render(Shape &shape) 
{ 
    shape.draw(); 
    shape.visible(true); 
} 

Thậm chí là nó hợp lệ để làm:

engine.render(myTriangle); // myTriangle instance of class derived from Shape 

Nếu công trình này, được có bất kỳ sự khác biệt giữa hai trường hợp? Tôi đã cố tìm thông tin trong Stroustrup, nhưng tôi không tìm thấy gì cả.

Tôi mở cửa trở lại vì tôi muốn khám phá thêm một chút nữa.

Vì vậy, ít nhất một sự khác biệt là dynamic_cast. Đối với tôi, đa hình bao gồm việc sử dụng dynamic_cast.

Tôi có thể đi

Rhomboid & r = dynamic_cast<Rhomboid &>(shape); 

gì sẽ xảy ra nếu các diễn viên không? Điều này có khác gì không?

Rhomboid * r = dynamic_cast<Rhomboid*>(&shape); 

Trả lời

38

Đối với đa hình, tham chiếu hoạt động giống như con trỏ.

+2

@ pm100: Trực tiếp, chắc chắn, nhưng có các khía cạnh khác nhau. Ví dụ, 'dynamic_cast' sẽ ném một ngoại lệ hơn là trả về null trên một dàn diễn viên xấu. – GManNickG

+2

@GMan: Tôi nghĩ về ví dụ 'dynamic_cast' là sự khác biệt cơ bản giữa con trỏ và tham chiếu: con trỏ có thể là NULL một cách hợp pháp, trong khi tham chiếu không thể. Trung tâm của câu hỏi, như tôi đã đọc, liệu các tham chiếu có hoạt động giống nhau không đối với các bảng ảo. Do đó câu trả lời ngắn gọn. –

+1

Cách tôi nhìn thấy nó, tài liệu tham khảo có vẻ là ít hơn so với cú pháp đường trên đầu trang của con trỏ. –

0

Con trỏ trợ giúp theo những cách khác. Giống như truyền một chuỗi và chấp nhận nó như tham số char * trong một hàm.

xem xét ví dụ cũ của đảo ngược một chuỗi tại chỗ: Mã

void reversestring(char* myString) 
{ 
int firstPos=0; 
int lastPos=myString.length - 1; 
while (firstPos < lastPos) 
{ 
    char temp=myString[firstPos]; 
    myString[firstPos]=myString[lastPos]; 
    myString[lastPos]=temp; 
    firstPos++; 
    lastPos--; 
} 
} 

Viết cho thao tác chuỗi như thế này sử dụng tài liệu tham khảo sẽ không thể là đơn giản.

+0

myString.length?Có phải đó là C++? –

+1

@TheLightSpark Nó sẽ hợp lệ nếu 'myString' là một chuỗi' std :: string', nhưng tôi tin rằng nó không hợp lệ đối với chuỗi C thô. Ngoài ra, 'length' nên là một cuộc gọi hàm, nhưng đó là nitpicking. –

7

Liên quan đến dynamic_cast, một dàn diễn viên không thành công tạo ra một con trỏ null với con trỏ, và dẫn đến một trường hợp ngoại lệ là bad_cast (IIRC) với tham chiếu.

Một lý do là không có thứ gì như tham chiếu null hợp lệ.

Và có thể một lý do khác (nhưng nó có thể chỉ là một tính năng nổi bật vô tình hữu ích) là đôi khi bạn cần ngoại lệ và đôi khi cần có con trỏ null dễ kiểm tra và không cần biết bạn có tham chiếu hay trỏ hay không tay phải mất tối đa một nhà điều hành dereferencing hoặc địa chỉ để có được hành vi mà bạn muốn.

Chúc mừng & hth.,

Các vấn đề liên quan