2013-11-20 14 views
5
void foo(MyClass* myClass) 
{ 
    BaseClass* pBaseClass = dynamic_cast<BaseClass*>(myClass); 
    delete myClass; // <-------------- Does this affects on pBaseClass ? 
} 

Nói chung, cách dynamic_cast thực sự hoạt động? (nó hoạt động giống như một nhà xây dựng sao chép?)Có an toàn khi xóa con trỏ sau khi dynamic_casting không?

+0

Nếu bạn làm muốn có một bản sao (và giả sử BaseClass thực sự là một lớp cơ sở) sau đó 'BaseClass bc = * lớp; ' – john

+0

Nếu' BaseClass' là thực sự là một lớp * base *, thì điểm đó là gì 'dynamic_cast' ??? Hoặc bất kỳ diễn viên nào cho vấn đề đó? – AnT

Trả lời

5

(Lưu ý rằng class không phải là tên biến hợp lệ vì đó là từ khóa. Tôi sẽ gọi nó là c thay thế).

Có an toàn khi xóa con trỏ sau khi dynamic_casting không?

Có; nhưng hãy cẩn thận rằng cả hai con trỏ đều không hợp lệ sau khi xóa đối tượng mà chúng trỏ đến. Bạn không thể sử dụng giá trị con trỏ sau đó.

Nói chung, dynamic_cast thực sự hoạt động như thế nào?

Nó chuyển đổi con trỏ hoặc tham chiếu đến loại lớp thành con trỏ hoặc tham chiếu đến loại lớp khác, với kiểm tra thời gian chạy để chuyển đổi hợp lệ. Trong trường hợp này, diễn viên sẽ thành công (đưa ra một con trỏ hợp lệ) nếu BaseClass giống như, hoặc một lớp cơ sở của, kiểu động của đối tượng. Nó sẽ thất bại (đưa ra một con trỏ null) nếu không.

Nếu bạn đang đúc *c thành loại tham chiếu, thì lỗi sẽ gây ra ngoại lệ (std::bad_cast), vì không có tham chiếu null nào.

nó hoạt động như một nhà xây dựng sao chép?

No. Sao chép trình tạo để sao chép đối tượng. Đây không phải là sao chép nó, chỉ cần thay đổi loại của một con trỏ trỏ đến nó. Một bản sao sẽ trông như thế

BaseClass bc = *c; 

Lưu ý rằng loại bcBaseClass, không phải là loại c (đó là đoán được một lớp học có nguồn gốc từ BaseClass); điều này được gọi là "cắt", vì phần có nguồn gốc của đối tượng bị "cắt đứt" và không được sao chép.

7

Không,không phải là an toàn. dynamic_cast chỉ là một loại chuyển đổi - cả điểm gốc và con trỏ được chuyển đổi thành cùng một đối tượng. Có thể con trỏ được chuyển đổi sẽ trỏ đến một địa chỉ hơi khác (nếu có nhiều thừa kế), nhưng nó vẫn trỏ vào trong cùng một đối tượng - không xảy ra việc sao chép đối tượng.

Chỉnh sửa: Tôi có nghĩa là "không an toàn" theo nghĩa "sau khi bạn delete myClass, pBaseClass là một con trỏ lơ lửng." Nó vẫn là mã pháp lý, mặc dù. Khá nguy hiểm.

+0

Tại sao không? 'dynamic_cast' hoặc thành công, sau đó tồn tại một mối quan hệ thừa kế mà làm cho cả hai diễn viên và gọi' xóa' hợp pháp (destructor đúng sẽ được hầu như gửi đi). Hoặc 'dynamic_cast' trả về' nullptr', điều này cũng an toàn. Tiêu chuẩn định nghĩa 'xóa nullptr' là no-op. – Damon

+0

@Damon Đã thêm giải thích; Tôi đã có một ấn tượng mạnh mẽ đó là ý nghĩa của "an toàn" mà OP là sau. – Angew

+1

Ah OK, tôi đã không xem xét một người có thể cố gắng vẫn sử dụng con trỏ ban đầu sau khi xóa. Điểm hợp lệ :-) – Damon

0

Vì bạn đang xử lý con trỏ, nó chỉ là giá trị của con trỏ được sao chép (tức là, chỉ địa chỉ).

Dưới đây là một lời giải thích đàng hoàng cho mã tương tự

C++ Does casting create a new object?

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