Loại trả về của hàm ảo phải là cùng loại nằm trong lớp cơ sở hoặc biến thể. Nhưng tại sao chúng ta có hạn chế này?Loại trả về khác nhau cho các chức năng ảo
Trả lời
Vì mã sẽ sử dụng giá trị trả về như thế nào đối phó với tất cả các loại loại không liên quan sắp trở lại? ví dụ .:
class A
{
public:
virtual float func();
};
class B: public A
{
public:
virtual char *func();
};
A *p = (some_condition) ? new A() : new B();
p->func(); // Oh no! What is the type?
Có, loại không liên quan = xấu. Còn các loại liên quan khác thì sao? – curiousguy
Do vô nghĩa đó sẽ xảy ra sau:
struct foo
{
virtual int get() const { return 0; }
};
struct bar : foo
{
std::string get() const { return "this certainly isn't an int"; }
};
int main()
{
bar b;
foo* f = &b;
int result = f->get(); // int, right? ...right?
}
Nó không phải là hợp lý để có một xuất phát trở lại một cái gì đó hoàn toàn không liên quan lớp.
Thảo luận [chuyển sang trò chuyện.] (Http://chat.stackoverflow.com/rooms/15288/discussion-between-gmannickg-and-curiousguy) – GManNickG
Kết luận của cuộc trò chuyện: ** GManNickG thừa nhận rằng quy tắc C++ hiện tại chỉ cho phép con trỏ (hoặc tài liệu tham khảo) có thể được thoải mái. ** – curiousguy
Không phải là một "thừa nhận", tôi không bao giờ phủ nhận nó ở nơi đầu tiên ... – GManNickG
Theo C++ Standard:
Kiểu trả về của một chức năng quan trọng hơn sẽ là một trong hai giống với kiểu trả về của các ghi đè func- tion hoặc hiệp biến với các lớp học của các chức năng. Nếu một hàm D :: f ghi đè một chức năng B :: f, các loại trở lại của các chức năng là hiệp biến nếu họ đáp ứng các tiêu chí sau:
1) cả hai đều là con trỏ đến các lớp học hoặc tham chiếu đến các lớp học
2) lớp trong kiểu trả về của B :: f là cùng một lớp với lớp trong kiểu trả về của D :: f, hoặc là một lớp cơ sở trực tiếp hoặc gián tiếp có thể truy cập hoặc gián tiếp của lớp trong loại trả về của D :: f
3) cả hai con trỏ hoặc tham chiếu es có cùng trình độ cv và loại lớp trong kiểu trả về của D :: f có cùng trình độ cv bằng hoặc ít cv-qualification hơn loại lớp trong kiểu trả về của B :: f.
Câu hỏi đã cho thấy hạn chế, nó hỏi tại sao hạn chế này tồn tại. – GManNickG
Câu trả lời rất giống với câu trả lời cho "Why can't I assign a vector<Apple*> to a vector<Fruit*>?" về Câu hỏi thường gặp của Bjarne Stroustrup.
Khả năng sửa đổi loại trả về sẽ dẫn đến lỗ hổng trong loại an toàn của ngôn ngữ (xem câu trả lời từ @GManNickG để biết ví dụ cụ thể) khi xử lý các loại đa hình.
Có một tình huống khá phổ biến khi ảnh hưởng đến kiểu trả về sẽ là lý tưởng: khi trả về một con trỏ đa hình từ một phương thức ảo của một kiểu cơ sở. Ví dụ:
class Base {
public:
virtual Base* parent() = 0;
};
class Child : public Base {
public:
Base* parent() override
{
return parent_;
}
private:
Parent* parent_; // Assume `Parent` type exists.
};
Ở đây chúng tôi đã mất thông tin loại Child
biết về thành viên parent_
. Điều này dẫn đến rất nhiều đúc, mặc dù loại đã được tại một điểm cũng được xác định. Chúng tôi có thể giải quyết vấn đề này bằng cách sử dụng thành ngữ Curiously Recurring Template Parameter (CRTP),
template<class ParentType>
class Base {
public:
virtual ParentType* parent()
{
return parent_;
}
private:
ParentType* parent_;
};
class Child : public Base<Parent> {
};
"_Câu trả lời rất giống với câu trả lời cho" Tại sao tôi không thể gán một vector
- 1. Haskell chức năng sàn trả về kết quả khác nhau
- 2. C# Trả về các loại khác nhau?
- 3. Loại trả về Scala cho các chức năng tuple
- 4. RankNTypes: áp dụng các chức năng tương tự cho các cặp của các loại khác nhau
- 5. Chức năng mẫu trong C# - Loại trả về?
- 6. Scala trả về các loại khác nhau cho các biểu thức rất giống
- 7. trả về các giá trị khác nhau cho c & C++?
- 8. Tại sao chức năng này trả về một giá trị khác nhau mỗi lần?
- 9. Câu hỏi với các chức năng ảo
- 10. Cách trả về các lớp khác nhau từ một hàm?
- 11. chức năng ảo const vs chức năng ảo không const
- 12. Độ dài mysql() cho các ngôn ngữ khác nhau trả về kích thước khác nhau
- 13. Thừa kế chức năng ảo
- 14. Sự khác biệt về chức năng mysqli_fetch
- 15. Các nhóm Mulitprocess với các chức năng khác nhau
- 16. Chức năng C++ trả về const char *
- 17. Vb Chức năng trả về null
- 18. Lẫn lộn về tên lẩn trốn và chức năng ảo
- 19. Chức năng jQuery ajax trả về lỗi
- 20. Chức năng trả về mảng BYTE
- 21. Ghi đè các chức năng ảo công cộng với các chức năng riêng tư trong C++
- 22. loại các loại trong các chức năng
- 23. PHP Chức năng trả về chuỗi
- 24. Chức năng trả về biểu thức lambda
- 25. Chức năng PHP trả về hai mảng
- 26. chức năng php trả về 0?
- 27. typecasting với các chức năng ảo
- 28. Sử dụng chức năng Chuyển qua chức năng khác nhau
- 29. Tại sao phân bổ ảo hoạt động khác với các chức năng ảo khác của cùng một chữ ký?
- 30. Sự khác biệt giữa việc gọi hàm ảo và chức năng ảo không?
Bạn dự kiến loại trả lại của chức năng ghi đè được phép ...? – curiousguy