Chuyển đổi con trỏ đóng vai trò là static_cast
. 5.2.9/2 cho biết,
Nếu đối tượng của loại [A
] thực sự là một subobject của một đối tượng của loại [B
], kết quả đề cập đến đối tượng kèm theo các loại [B
]. Nếu không, kết quả của dàn diễn viên sẽ không được xác định.
Đối tượng của bạn là không một subobject của một đối tượng B
, vì vậy kết quả là không xác định.
Ngay cả khi bạn đã đến reinterpret_cast
, việc truy cập giá trị của đối tượng thông qua con trỏ kết quả có hành vi không xác định do vi phạm bí danh nghiêm ngặt. Trong tiêu chuẩn C++ 11, 3.10/10:
Nếu một chương trình cố gắng truy cập vào các giá trị được lưu trữ của một đối tượng thông qua một glvalue của khác hơn là một trong các loại sau đây hành vi này là fi unde định nghĩa:
"Một lớp học có nguồn gốc của loại động của đối tượng không thêm thành viên dữ liệu hoặc chức năng thành viên ảo "là không phải là trong danh sách sau.
Tùy thuộc vào những gì method1
thực sự làm, có thể tránh truy cập vào giá trị được lưu trữ của đối tượng khi gọi. Nhưng tôi không chắc nó có thể làm được không. Trừ khi được nêu khác đi trong tiêu chuẩn, tôi sẽ giả định cho sự an toàn gọi hàm thành viên không tĩnh vốn "truy cập giá trị được lưu trữ của đối tượng" ngay cả khi chức năng không thực sự sử dụng bất kỳ thành viên dữ liệu nào.
Đây là một trong những trường hợp khó xử đó có thể sẽ hoạt động trong thực tế hoặc là mọi lúc hoặc gần như mọi lúc. Nhưng nó không được bảo đảm, do đó, ngay cả khi nó xuất hiện để làm việc và mã phát ra có vẻ OK, bạn sẽ sống trong sợ hãi rằng một ngày nào đó một tối ưu hóa mới sẽ phá vỡ nó.
Sau khi được xác định, các lớp C++ được đóng cho các thành viên mới, bao gồm các hàm thành viên mới. Vì vậy, đối tượng của bạn tạo ra với new A()
có tất cả các chức năng thành viên nó sẽ bao giờ có. Chỉ cần viết một chức năng không phải là thành viên - trừ khi A
có protected
thành viên, nó sẽ có quyền truy cập chính xác vào A
mà chức năng thành viên của bạn có. Và nếu A
không có protected
thành viên thì có được phê duyệt cách lấy từ nó, mà bạn nên sử dụng để tạo các phiên bản thích hợp B
.
Nếu cú pháp hàm thành viên có nghĩa là nhiều cho bạn, sau đó tùy thuộc vào lớp A
bạn có thể có thể viết:
B b = *a; // "copy" the object (give B a suitable ctor)
b.method1(); // act on it
*a = b; // copy it back (A needs copy assignment operator)
Rõ ràng là có vấn đề ở đây là có thể ngăn chặn nó làm việc: để bắt đầu với liệu đối tượng là có thể sao chép, cũng an toàn chủ đề và liệu method1
lưu trữ một con trỏ/tham chiếu đến b
ở đâu đó sẽ bắt đầu dangle ngay sau khi b
bị hủy. Trong C++ 11 các bản sao có lẽ có thể di chuyển hiệu quả, nhưng thậm chí vì vậy tôi hy vọng bạn sẽ đồng ý rằng các vòng bạn phải nhảy qua để sử dụng cú pháp hàm thành viên không đáng giá.
Không, 'A' không phải là' B'. –
Câu hỏi của bạn không khớp với những gì bạn đang yêu cầu. Câu hỏi của bạn hỏi về việc truyền các đối tượng, trong khi mã của bạn đang truyền con trỏ. – Mehrdad
Liên quan: http://stackoverflow.com/questions/11404209/c-memory-layout-of-inheritance – jogojapan