2012-08-07 39 views
11

Tôi có lớp cơ sở của tôi như sau:C++ thừa kế downcasting

class point //concrete class 
{ 
... //implementation 
} 

class subpoint : public point //concrete class 
{ 
...  //implementation 
} 

Làm thế nào để đúc từ một đối tượng hướng đến một đối tượng subpoint? Tôi đã thử cả ba điều sau đây:

point a; 
subpoint* b = dynamic_cast<subpoint*>(&a); 
subpoint* b = (subpoint*)a; 
subpoint b = (subpoint)a; 

Điều gì là sai với các phôi này?

Trả lời

22

Làm cách nào để truyền từ đối tượng điểm đến đối tượng điểm phụ?

Bạn không thể; trừ khi point có toán tử chuyển đổi hoặc subpoint có một hàm tạo chuyển đổi, trong trường hợp này, các loại đối tượng có thể được chuyển đổi mà không cần một dàn diễn viên.

Bạn có thể đúc từ một pointtham khảo (hoặc con trỏ) vào một subpointtham khảo (hoặc con trỏ), nếu đối tượng được gọi là thực sự là loại subpoint:

subpoint s; 

point & a = s; 
subpoint & b1 = static_cast<subpoint&>(a); 
subpoint & b2 = dynamic_cast<subpoint&>(a); 

đầu tiên (static_cast) nguy hiểm hơn; không có kiểm tra xem chuyển đổi có hợp lệ hay không, vì vậy nếu a không tham chiếu đến subpoint, thì việc sử dụng b1 sẽ có hành vi không xác định.

Thứ hai (dynamic_cast) là an toàn hơn, nhưng sẽ chỉ hoạt động nếu point là đa hình (nghĩa là, nếu nó có chức năng ảo). Nếu a đề cập đến một đối tượng không tương thích, thì nó sẽ ném một ngoại lệ.

+0

Đối tượng sẽ được đúc thực sự là loại điểm phụ, nó chỉ nằm trong một mảng các điểm. – CodeKingPlusPlus

0

a không thể được thực hiện thành subpoint. triển khai đó không có ở đó.

0

Điều gì là sai với các phôi này?

Thực tế là bạn cố gắng thực hiện chúng. A point không phải là subpoint, tôi sẽ ngạc nhiên nếu nó hoạt động.

1

Nhìn chung, điều này sẽ không hoạt động vì point không phải là subpoint; chỉ ngược lại là đúng. Tuy nhiên, cũng có những vấn đề khác.

Thứ tự:


subpoint* b = dynamic_cast<subpoint*>(&a); 

dynamic_cast chỉ hoạt động trên các loại đa hình, ví dụ, các loại thực hiện kê khai ít nhất một chức năng ảo. Tôi đoán là point không có chức năng ảo, có nghĩa là nó không thể được sử dụng với dynamic_cast.


subpoint* b = (subpoint*)a; 

Đối với dàn diễn viên này để làm việc, point nhu cầu tuyên bố một nhà điều hành chuyển đổi sang subpoint *, ví dụ, point::operator subpoint *().


subpoint b = (subpoint)a; 

Đối với dàn diễn viên này để làm việc, điểm cần phải tuyên bố một nhà điều hành chuyển đổi sang subpointhaysubpoint nhu cầu phải có một nhà xây dựng mà phải mất một convertable tham số từ point.

2

Ví dụ đầu tiên, dynamic_cast chỉ hoạt động nếu có ít nhất một phương pháp ảo trong lớp cơ sở. Và nếu đối tượng không thực sự thuộc loại bạn đang cố gắng truyền, nó sẽ dẫn đến NULL.

Ví dụ thứ hai bạn cần &a thay vì a, nhưng khi bạn đã khắc phục rằng bạn sẽ nhận được hành vi không xác định do loại đối tượng sai.

Ví dụ thứ ba yêu cầu phương thức operator subpoint() trong point để thực hiện chuyển đổi trong khi tạo bản sao.

+1

@MooingDuck, xác định "sẽ không làm việc"? Nó sẽ trả về một con trỏ NULL, có thể không phải là kết quả mong đợi nhưng nó biên dịch và làm một cái gì đó hữu ích. –

+0

Tôi phải đọc sai câu trả lời của bạn, bây giờ có vẻ ổn với tôi. –

1

Mục đích của diễn viên động là "kiểm tra tại thời gian chạy nếu đối tượng thuộc loại nhất định trong phân cấp". Bây giờ, hãy xem những gì bạn có:

  1. Bạn có đối tượng điểm. Không phải là một điểm phụ.
  2. Bạn đang hỏi một diễn viên năng động nếu đối tượng là một điểm phụ. Nó không phải.
  3. Vì không phải là điểm phụ, dynamic_cast không thành công - cách cho bạn biết rằng đối tượng không phải là loại bạn đang cố gắng truyền.

Ngược lại, điều này sẽ làm việc:

subpoint c; 
point *a = &c; 
subpoint* b = dynamic_cast<subpoint*>(&a); 
subpoint* b = (subpoint*)a;