Tôi đang cố gắng sử dụng lớp cơ sở trừu tượng C++ theo cách tương tự với giao diện Java. Cho rằng chúng tôi đã theo các lớp giao diện với các chức năng ảo chỉ thuần túy:Thừa kế song song giữa các lớp giao diện và lớp triển khai trong C++
class Shape { virtual double area()=0; };
class Square : public Shape { virtual void setLength(double length)=0; };
class Rectangle : public Square { virtual void setWidth(double width)=0; };
và tôi cố gắng thực hiện Square và Rectangle theo cách sau:
class SquareImpl : public Square { /*implementation*/ };
class RectangleImpl : public SquareImpl, Rectangle { /*implementation*/ };
đâu RectangleImpl
thừa hưởng cả SquareImpl
và Rectangle
để tái sử dụng, nói , SquareImpl::area()
. Tuy nhiên khi tôi cố gắng biên dịch, hai vấn đề phát sinh: Thứ nhất, tất cả các phương thức trong SquareImpl
không được kế thừa đúng cách và tôi phải thực hiện lại thủ công RectangleImpl::area()
và RectangleImpl::setLength()
. Thứ hai, điều này vẫn giới thiệu vấn đề kim cương mà Shape
là cơ sở mơ hồ của RectangleImpl
.
Tôi có thể biên dịch mã nếu tôi hầu như kế thừa Square
từ Shape
, nhưng tôi không nghĩ rằng hiệu suất sẽ mở rộng với nhiều giao diện xuất phát hơn được thêm vào. Ngoài ra, RectangleImpl
vẫn không kế thừa SquareImpl::setLength()
mặc dù SquareImpl::area()
được kế thừa tốt. (bỏ qua tính thực tiễn tại đây)
Một giải pháp khác có thể là làm cho giao diện độc lập với nhau, tức là làm cho Square
không được kế thừa từ Shape
. Nhưng làm như vậy sẽ làm cho tôi mất quyền truy cập vào các phương thức trong Shape
nếu tôi định nghĩa các hàm lấy con trỏ Square*
. Nó cũng sẽ làm cho static_cast không thể giữa Shape
và Square
. Vì vậy, câu hỏi của tôi là, có bất kỳ mẫu thiết kế nào khác trong C++ để giải quyết loại thừa kế song song này giữa các lớp giao diện và các lớp thực hiện, mà không yêu cầu thừa kế ảo không? Không.
(chỉnh sửa làm rõ: mã ví dụ trên chỉ là minh họa hình nộm của tôi về thừa kế song song giữa các giao diện và hiện thực Tôi hiểu rằng có những cách tốt hơn để thực hiện hình dạng nhưng vấn đề của tôi không phải là làm thế nào để thực hiện hình dạng..)
"Nơi RectangleImpl kế thừa cả SquareImpl và Rectangle để tái sử dụng, SquareImpl :: area()" => kế thừa để được sử dụng lại, không sử dụng lại. – icecrime
dupe của http://stackoverflow.com/questions/249500/looking-for-a-better-way-than-virtual-inheritance-in-c? –
Việc thừa kế không công khai của Hình chữ nhật trong RectangleImpl có dự định không? – daramarak