Lần này chúng ta thay đổi cách chúng ta đối xử với những chú chó một chút. Hãy xem ví dụ →
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <iostream> #include <string> using namespace std; class Pet { protected: string name; public: Pet(string name) : name(name) {} virtual void MakeSound(void) { cout << name << " is silent :(" << endl; } }; class Dog : public Pet { public: Dog(string name) : Pet(name) {} void MakeSound(void) { cout << name << " says: Woof!" << endl; } }; class GermanShepherd : public Dog { public: GermanShepherd(string name) : Dog(name) {} void MakeSound(void) { cout << name << " says: Wuff!" << endl; } void Laufen(void) { cout << name << " runs (gs)!" << endl; } }; class MastinEspanol : public Dog { public: MastinEspanol(string name) : Dog(name) {} void MakeSound(void) { cout << name << " says: Guau!" << endl; } void Ejecutar(void) { cout << name << " runs (mes)!" << endl; } }; void PlayWithPet(Pet &pet) { pet.MakeSound(); dynamic_cast<GermanShepherd &>(pet).Laufen(); dynamic_cast<MastinEspanol &>(pet).Ejecutar(); } int main(void) { Pet pet("creature"); Dog dog("Dog"); GermanShepherd gs("Hund"); MastinEspanol mes("Perro"); PlayWithPet(pet); PlayWithPet(dog); PlayWithPet(gs); PlayWithPet(mes); return 0; } |
Tham số của hàm PlayWithPet không phải là con trỏ mà là một tham chiếu. Do đó 2 thành phần sau của chương trình cũng đã được thay đổi theo:
- Hàm main gọi hàm PlayWithPet theo một cách khác
- Cách sử dụng dynamic_cast cũng hơi khác một chút, nó có dạng sau:
dynamic_cast<reference_type>(reference_to_object)
dynamic_cast trong trường hợp này trả về biến tham chiếu đã được chuyển đổi, kết quả là nó có thể được sử dụng như một giá trị l-value bình thường.
Có một vấn đề quan trọng mà chúng ta cần xem xét ở đây, đó là: Điều gì sẽ xảy ra khi toán tử dynamic_cast không thể thực hiện việc chuyển đổi kiểu ?
Trong ví dụ trước, chúng ta kiểm tra giá trị trả về của biểu thức ép kiểu để quyết định có làm một việc gì đó hay không. Còn trong trường hợp này chúng ta sẽ không làm như vậy được.
Hãy biên dịch và chạy chương trình, bạn sẽ thấy một kết quả khá thốn. Trên Windows, nếu bạn biên dịch chương trình sử dụng Visual Studio 2015 và chạy chương trình lên thì kết quả sẽ kiểu như sau:
Hình thức của thông báo có thể khác nếu bạn sử dụng trình biên dịch khác hoặc chạy trên hệ điều hành khác. Tuy nhiên có một thứ sẽ giống nhau là trên console sẽ chỉ có một dòng text duy nhất, đó là:
1 |
creature is silent :( |
và kèm theo một thông báo rằng chương trình của bạn đã bị chấm dứt do lỗi runtime.
Vậy kết luận ở đây là gì ? Đó làChúng ta không được phép sử dụng một biến tham chiếu (hoặc con trỏ) là kết quả của việc ép kiểu mà không chắc chắn rằng việc ép kiểu đó thành công.
Chúng ta đã biết làm thế nào để kiểm tra kết quả ép kiểu đối với con trỏ. Nhưng với biến tham chiếu thì phương pháp đó không thể sử dụng được. Chúng ta vẫn có cách để thực hiện việc kiểm tra đối với tham chiếu để đảm bảo cho chương trình khỏi ảnh hưởng của việc ép kiểu không thành công. Đó chính là xử lý ngoại lệ – exception. Hãy chuyển sang trang tiếp theo để xem ví dụ cụ thể 👉