Tôi có đoạn mã sau:Tại sao giá trị của một con trỏ đến thành viên luôn giống nhau cho các thành viên khác nhau của cùng một cấu trúc?
#include <iostream>
#include <string>
using namespace std;
struct foo_s {
string a;
string b;
string c;
};
void print_field(foo_s* foo, string foo_s::* field) {
cout << "field: " << field << " - " << foo->*field << endl;
}
int main() {
foo_s my_foo = {
"a",
"b",
"c",
};
print_field(&my_foo, &foo_s::a);
print_field(&my_foo, &foo_s::b);
print_field(&my_foo, &foo_s::c);
return 0;
}
đầu ra của nó là:
field: 1 - a
field: 1 - b
field: 1 - c
Tôi đang gặp một chút rắc rối tìm hiểu những đặc trưng của những gì đang xảy ra trong print_field()
chức năng. Cụ thể:
- Loại
field
là gì? Tôi tưởng tượng nó làpointer-to-string-foo_s-member
- Tại sao giá trị của
field
luôn giống nhau (1 trong trường hợp này), nhưngfoo->*field
cho kết quả khác nhau?
Chủ yếu, tôi bị bối rối ở # 2. Tôi tưởng tượng lĩnh vực sẽ được một "bù đắp" từ khi bắt đầu của cấu trúc và foo->*field
sẽ là khái niệm tương đương với một cái gì đó giống như
char* ptr = static_cast<char*>(foo);
ptrdiff_t offset = somehow_get_the_byte_offset_from_pointer_to_member(field);
ptr = ptr[offset];
string result = *static_cast<string*>(ptr);
nhưng điều đó có vẻ là ra vì giá trị field
's không khác nhau giữa các cuộc gọi. Tôi đang thiếu gì? Làm thế nào chính xác là hoạt động cụ thể này được mô tả theo tiêu chuẩn?
Chà, điều đó dạy tôi ở lại với bản in cũ tốt và nếu chỉ vì tôi hiểu nó tốt hơn. – martin
@martin: Điều đó sẽ cho hành vi không xác định nếu bạn cố gắng in một con trỏ thành viên. C++ I/O ít nhất là an toàn, nếu đôi khi khó hiểu. –
@martin Câu hỏi thú vị - bạn định sử dụng định dạng nào cho con trỏ tới thành viên? Bạn thậm chí không biết kích thước của sự vật (nói chung). – Angew