2012-03-14 33 views
16

thể trùng lặp:
C++ equivalent of instanceofC++ dynamic_cast vs typeid để so sánh lớp

tôi đã tự hỏi những gì là sự khác biệt giữa dynamic_casttypeid là liên quan đến so sánh chỉ lớp (ngoài dynamic_cast cho phép truy cập vào các phương thức của lớp con và loại id chỉ hữu ích cho việc so sánh lớp). Tôi đã tìm thấy StackOverflow hai tuổi hỏi cùng một câu hỏi: C++ equivalent of instanceof. Tuy nhiên, đó là hai tuổi và tôi không muốn necro một bài cũ (và tôi không chắc chắn khi typeid xuất hiện), vì vậy tôi nghĩ lại hỏi cùng một câu hỏi với một sự khác biệt nhỏ. Về cơ bản, tôi có lớp A và lớp B, cả hai đều là lớp con của lớp trừu tượng C. Lớp C được lấy làm tham số cho một phương thức và tôi muốn xác định xem lớp C có thực sự là lớp A hay lớp B hay không. Cả hai typeiddynamic_cast hoạt động đúng cách vì vậy đây là câu hỏi về thực hành/hiệu suất tốt nhất. Tôi đoán:

A* test = dynamic_cast<A*> someClassCVar 
if (test != 0) { //it is of class A } 

HOẶC

if (typeid(someClassCVar) == typeid(A)) { 
    //it is of class A 
} 

EDIT: Xin lỗi, tôi quên bao gồm chút thông tin này. Tài liệu ActiveMQ CMS nêu rõ sử dụng dynamic_cast, nhưng tôi nghĩ rằng đó là chỉ vì nó giả sử người dùng sẽ muốn truy cập các phương thức cụ thể cho lớp con. Đối với tôi, dường như typeid sẽ là hiệu suất tốt hơn nếu chỉ so sánh đẳng cấp là cần thiết: http://activemq.apache.org/cms/cms-api-overview.html

+1

Tôi muốn nói 'cái dynamic_cast' là được ưa thích, nhưng tôi không có nguồn để sao lưu của tôi ý kiến. – Constantinius

+3

'dynamic_cast someClassCVar' sẽ trả về giá trị không null nếu' someClassCVar' là một con trỏ tới 'A' hoặc bất kỳ phần tử con nào của' A'. 'typeid (someClassCVar) == typeid (A)' là true chỉ khi 'someClassCVar' là kiểu A. Vì vậy, 2 phần mã của bạn không tương đương. – a1ex07

+3

Thông thường nó là một mùi thiết kế nếu một chương trình C++ cần biết lớp con nào mà một con trỏ cha trỏ tới. Bạn nên ít nhất bước trở lại trong 15 phút và nhìn vào thiết kế của bạn. –

Trả lời

25

Có một sự khác biệt quan trọng giữa hai phương pháp:

if(A* test = dynamic_cast<A*>(&someClassCVar)) { 
    // someClassCVar is A or publicly derived from A 
} 

Trong đó:

if(typeid(someClassCVar) == typeid(A)) { 
    // someClassCVar is of class A, not a derived class 
} 
+0

Ahh, tôi hiểu. Vì vậy, nếu chúng ta không quan tâm nếu nó là A hoặc phân lớp A vì một lý do nào đó, điều đó sẽ tốt hơn? – Jon

+2

@Jon: rõ ràng là cái đầu tiên;) – Constantinius

+1

'dynamic_cast <>' sau đó, vì bạn chỉ quan tâm đến giao diện của 'A' và không quan tâm nó được triển khai như thế nào. –

0

nó phụ thuộc nếu bài kiểu chế biến xác định cần một con trỏ trên A hay không.

cheking typeid chắc chắn sẽ nhanh hơn (vì trình biên dịch tạo ra các định danh không đổi) nhưng sẽ không cung cấp bất kỳ cá thể A nào để thao tác để bắt buộc bạn thực hiện dynamic_cast để lấy một cá thể A.

+4

... hoặc static_cast nếu C là lớp cơ sở không phải ảo cho A và B – user396672