Từ cuộc thảo luận của câu hỏi này How is access for private variables implemented in C++ under the hood? Tôi đã đặt một biến thể: thay vì truy cập vào một thành viên dữ liệu riêng tư, có thể gọi một hàm thành viên riêng thông qua truyền và dựa vào tính tương thích của bố cục không?Có thể truy cập các chức năng thành viên riêng tư thông qua truyền tới các loại tương thích với bố cục không?
Một số mã (lấy cảm hứng từ cột Herb Sutter Uses and Abuses of Access Rights)
#include <iostream>
class X
{
public:
X() : private_(1) { /*...*/ }
private:
int Value() { return private_; }
int private_;
};
// Nasty attempt to simulate the object layout
// (cross your fingers and toes).
//
class BaitAndSwitch
// hopefully has the same data layout as X
{ // so we can pass him off as one
public:
int Value() { return private_; }
private:
int private_;
};
int f(X& x)
{
// evil laughter here
return (reinterpret_cast<BaitAndSwitch&>(x)).Value();
}
int main()
{
X x;
std::cout << f(x) << "\n"; // prints 0, not 1
return 0;
};
Lưu ý: đây làm việc (ít nhất là trên Ideone)! Có cách nào mới C++11 Standard cung cấp cho đảm bảo hoặc ít nhất một cách thực hiện được xác định cách để tránh sự kiểm soát truy cập bằng cách dựa vào khả năng tương thích bố cục và reinterpret_cast/static_cast không?
EDIT1: sản lượng trên Ideone
EDIT2: Trong cột Sutter, ông liệt kê hai lý do tại sao đoạn code trên không được bảo đảm để làm việc (mặc dù nó hoạt động trong thực tế)
a) Các bố trí đối tượng của X và BaitAndSwitch không được đảm bảo là giống nhau, mặc dù trong thực tế chúng có thể luôn luôn như vậy.
b) Kết quả của reinterpret_cast không được xác định, mặc dù hầu hết các trình biên dịch sẽ cho phép bạn cố gắng sử dụng tham chiếu kết quả theo cách thức của mà hacker dự định.
Chuẩn C++ 11 mới hiện cung cấp các đảm bảo bố cục/reinterpret_cast này?
Bạn có thể phá vỡ hầu hết mọi thứ bạn muốn bằng 'reinterpret_cast'; bạn có hỏi liệu có thể làm như vậy theo cách được xác định rõ ràng không? –
@OliCharlesworth Có, đảm bảo sẽ là tốt nhất, thực hiện được xác định thứ hai tốt nhất và UB không tốt như vậy. – TemplateRex
Không đời nào. Về phương thức lớp Assembly chỉ là hàm toàn cục với tham số "this" ẩn, nó không thuộc về instance class và không thể truy cập thông qua các thủ thuật layout. –