Tôi có đoạn mã này (contrived từ rắc rối thực tế cuộc sống của tôi)Sử dụng tham số kiểu phân lớp trong chức năng ảo
Nó không thể biên dịch, phàn nàn ExtendsB không thực hiện B::Run(A* a)
. Tuy nhiên, nó không có vấn đề tìm hiểu phần mở rộng để A* Run();
class A { };
class ExtendsA : public A { };
class B
{
public:
virtual ~B(){}
virtual void Run(A* a) = 0;
virtual A* Run() = 0;
};
class ExtendsB : public B
{
public:
virtual ~ExtendsB(){}
// Not OK! It does not see it as an implementation of
// virtual void Run(A* a) = 0;
virtual void Run(ExtendsA* ea) {};
virtual ExtendsA* Run() { return new ExtendsA(); }; // OK
};
Tại sao C++ cho phép thay đổi kiểu trả về một sub-class, nhưng không phải là kiểu tham số?
Đây có phải là lý do hợp lý hoặc chỉ là điểm bị thiếu trong thông số ngôn ngữ?
Đối với quy tắc đó, đối số không cần phải khớp 100%. Trong khi * đối số covariant * sẽ phá vỡ quy tắc đó, * đối số biến thể * sẽ không phá vỡ nó (mọi đối số có thể được chuyển tới cơ sở cũng có thể được chuyển đến kiểu bắt nguồn) và chúng cũng không được phép. Một phần của lý do là x-phương sai không đến miễn phí và phải được xử lý bởi trampoline/thunks mà sửa chữa các đối số trả về (trong trường hợp hiệp phương sai). Việc cho phép thay đổi contra trong các đối số rất lớn (theo cấp số nhân?) Tăng số lượng các hàm trampoline được yêu cầu và kích thước của bảng ảo. –