Tôi biết rằng C++ không hỗ trợ hiệp phương sai cho các phần tử vùng chứa, như trong Java hoặc C#. Vì vậy, đoạn mã sau có thể là hành vi không xác định:Hợp tác trung gian vùng chứa trong C++
#include <vector>
struct A {};
struct B : A {};
std::vector<B*> test;
std::vector<A*>* foo = reinterpret_cast<std::vector<A*>*>(&test);
Không ngạc nhiên khi tôi nhận được giải pháp này khi đề xuất giải pháp này cho another question.
Nhưng phần nào của tiêu chuẩn C++ chính xác cho tôi biết rằng điều này sẽ dẫn đến hành vi không xác định? Nó đảm bảo rằng cả hai std::vector<A*>
và std::vector<B*>
lưu trữ con trỏ của chúng trong một khối bộ nhớ. Nó cũng được đảm bảo rằng sizeof(A*) == sizeof(B*)
. Cuối cùng, A* a = new B
là hoàn toàn hợp pháp.
Vì vậy, những gì xấu tinh thần trong tiêu chuẩn đã làm tôi gợi ý (ngoại trừ phong cách)?
Việc sử dụng reinterpret_cast <>() sau đó không có gì được xác định. Nó có thể hoạt động nhưng danh sách các điều kiện của bạn quá ngắn ngủi. Tôi sẽ thêm một vài điều kiện trước. sizeof (A) == sizeof (B); Không phải A hoặc B có thể chứa bất kỳ loại chức năng ảo nào. Cả A và B cũng không phải bất kỳ hậu duệ nào được đặt trong mảng đều có thể sử dụng nhiều thừa kế. –
Câu trả lời cụ thể không phải C++ là nó không an toàn.Nếu bạn thêm một 'A' vào foo bạn có kiểm tra trong trạng thái không hợp lệ vì nó đảm bảo rằng tất cả các phần tử có kiểu' B'. Và C# cũng không hỗ trợ điều này. C# chỉ hỗ trợ nó cho các tham số chung được sử dụng trong các cách an toàn (chỉ có đầu vào hoặc đầu ra) và chỉ trên các giao diện và các đại biểu. Java hỗ trợ nó bởi vì nó bổ sung kiểm tra thời gian chạy và làm việc nội bộ trên lớp cơ sở đối tượng. – CodesInChaos
Câu hỏi này trông giống như http://stackoverflow.com/questions/842387/how-do-i-dynamically-cast-between-vectors-of-pointers – Nekuromento