Hãy nói rằng tôi có các loại sau:Làm thế nào để làm một khẳng định tĩnh rằng một con trỏ cast là tầm thường?
struct A {
int a;
};
struct B {
int b;
};
struct C : public A, public B {
int c;
};
Một con trỏ C*
có thể được đúc để A*
con trỏ mà không điều chỉnh địa chỉ thực tế chút nào. Nhưng khi C*
được truyền tới B*
, giá trị phải thay đổi. Tôi muốn đảm bảo rằng hai loại liên quan tôi có thể được đúc với nhau mà không thay đổi địa chỉ (nghĩa là không có nhiều thừa kế, hoặc lớp cơ sở là cơ sở đầu tiên của lớp dẫn xuất). Điều này có thể được kiểm tra tại thời gian chạy, ví dụ: giống như vậy
assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);
assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);
Điều đó có hiệu quả. Nhưng thông tin này được biết ở thời gian biên dịch, vì vậy tôi đang tìm cách để thực hiện một xác nhận biên dịch trên đó. Các cách rõ ràng để chuyển đổi ở trên thành một khẳng định tĩnh (ví dụ: thay thế assert
bằng lỗi BOOST_STATIC_ASSERT
cho lỗi "một loại bỏ với loại không phải là loại tích phân hoặc kiểu liệt kê không thể xuất hiện trong biểu thức không đổi" với g ++ 4.2.
Tính di động không phải là quá quan trọng Sử dụng tiện ích gcc, hoặc mẫu thủ đoạn hacky tất cả sẽ ổn thôi
cập nhật:.. Tìm thấy rằng gần như cùng một câu hỏi đã được hỏi trước:. C++, statically detect base classes with differing addresses? Sử dụng offsetof()
chỉ là gợi ý hữu ích ở đó quá.
Không muốn trở thành một nitpick, nhưng vì bố cục bộ nhớ chính xác là chi tiết triển khai ... tại sao bạn lại quan tâm đến điều này một cách chính xác? –
Tôi khá chắc chắn rằng thư viện Boost/lambda chứa nội dung cho việc này. Tôi phải xem xét nó nhưng Alexandrescu và Vandervoorde đã xuất bản chỉ là về mọi thủ thuật trong lĩnh vực này – sehe
Tôi thực sự quan tâm đến câu hỏi mà @Matthieu M. trình bày: Dưới những trường hợp nào có vấn đề nếu một diễn viên có thể tầm thường? (tức là nếu nó không nhỏ, chi phí có thể không đáng kể: thêm một hằng số vào con trỏ có nguồn gốc, và nếu điều kiện không được thực hiện đúng cách, bạn sẽ chạy vào cơn đau thực sự cố gắng gỡ lỗi bộ nhớ sẽ bị hỏng) –