Đa kế thừa trong C++

Không giống như nhiều ngôn ngữ lập trình hướng đối tượng khác, C++ có tính năng đa kế thừa (multiple inheritance). Đa kế thừa cho phép một lớp con (child class) kế thừa từ nhiều lớp cha (parent class).

Ngay từ đầu, đây có vẻ là một tính năng rất hữu ích, nhưng người dùng cần lưu ý đến một số điều cần biết khi triển khai tính năng này.

Trong các ví dụ dưới đây sẽ cho các bạn thấy một vài tình huống cần lưu ý. Chúng ta sẽ bắt đầu với một ví dụ đơn giản để giải thích khái niệm này trong C ++:

Đầu ra của mã này như sau:

Trong ví dụ trên, ta có một lớp cơ sở tên là LivingThing, các lớp Animal và Reptile kế thừa từ nó. Chỉ có lớp Animal ghi đè phương thức Breathe (). Lớp Snake kế thừa từ lớp Animal và Reptile, nó ghi đè các phương thức của chúng. 

Điều gì sẽ xảy ra nếu lớp Reptile ghi đè phương thức Breat ()?

Lớp Snake sẽ không biết nên gọi phương thức Breat () nào. Đây là "Vấn đề kim cương" (Diamond Problem).

 

Tổng hợp các việc làm C++ tại Vietnamworks

Diamond problem - Vấn đề kim cương

Nhìn vào đoạn code dưới đây, nó giống như đoạn code trong ví dụ trên, ngoại trừ việc chúng ta đã ghi đè phương thức Breathe () trong lớp Reptile: 

Nếu bạn cố gắng biên soạn chương trình, nó sẽ không thành công. Bạn sẽ nhìn chằm chằm vào thông báo lỗi như bên dưới:

Lỗi là do "Diamond Problem" của đa kế thừa, lớp Snake không biết nên gọi phương thức Breathe () nào.

Trong ví dụ đầu tiên, chỉ mỗi lớp Animal ghi đè phương thức Breathe (), lớp Reptile thì không. Do đó, lớp Snake không quá khó khăn khi tìm ra phương thức Breathe () nào để gọi. Cuối cùng, lớp Snake đã kết thúc việc gọi phương thức Breathe () của lớp Animal.

Trong ví dụ thứ hai, lớp Snake kế thừa hai phương thức Breathe (): phương thức Breathe () của lớp Animal và Reptile. Vì chưa ghi đè phương thức Breathe () trong lớp Snake, nên mọi thứ rất mơ hồ.

C ++ có nhiều tính năng mạnh mẽ như đa kế thừa. Tuy nhiên, không nhất thiết chúng ta phải sử dụng tất cả các tính năng mà nó cung cấp. Bạn có thể nghĩ ngay đến việc sử dụng kế thừa ảo (virtual inheritance) thay vì kế thừa.

Kế thừa ảo sẽ giải quyết “Vấn đề kim cương” kinh điển này, đảm bảo rằng lớp con sẽ chỉ nhận được một biến instance duy nhất của lớp cơ sở chung (common base class).

Nói cách khác, lớp Snake sẽ chỉ có một biến instance của lớp LivingThing. Các lớp Animal và Reptile sẽ chia sẻ biến instance này.

Điều này sẽ giúp bạn giải quyết lỗi thời gian biên dịch mà bạn nhận được trước đó. Các lớp dẫn xuất từ ​​các lớp trừu tượng (abstract classes) phải ghi đè các hàm ảo thuần túy được định nghĩa trong lớp cơ sở.

Tổng hợp việc làm IT - Software trên VietnamWorks
VietnamWorks InTECH
Theo freecodecamp