2012-07-15 21 views
6

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?

+0

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? –

+0

@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

+0

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. –

Trả lời

3

Có, bạn có thể tạo loại sử dụng cùng bố cục như loại bạn đang cố gắng để thêm vào, sau đó là reinterpret_cast từ loại đó đến loại tương thích bố cục của bạn. Nhưng điều này chỉ được bảo vệ theo tiêu chuẩn nếu cả hai loại nguồn và đích là loại bố cục chuẩn (và tất nhiên, nó chỉ thực sự hoạt động nếu bố cục của chúng giống nhau). Vì vậy, nếu nguồn có chức năng ảo, bạn sẽ bị hỏng.

Điều này dường như đáp ứng cả hai vấn đề của Sutter tại đây. Các quy tắc về bố cục chuẩn đảm bảo rằng hai loại bố cục chuẩn xác định cùng một thành viên theo cùng thứ tự đều tương thích với bố cục (phần 9.2, đoạn 17):

Hai cấu trúc bố cục tiêu chuẩn (Điều 9) các kiểu tương thích với bố trí nếu chúng có cùng số lượng thành viên dữ liệu không tĩnh và các thành viên dữ liệu không tĩnh tương ứng (theo thứ tự khai báo) có kiểu tương thích với bố cục (3.9).

Và các quy tắc cho reinterpret_cast rõ ý nghĩa của việc chuyển đổi giữa hai loại tiêu chuẩn bố trí (phần 5.2.10, đoạn 7):

Một con trỏ đối tượng có thể được chuyển đổi một cách rõ ràng để một con trỏ đối tượng một loại khác. Khi giá trị “con trỏ đến T1” được chuyển thành loại “con trỏ tới cv T2”, kết quả là static_cast<cv T2*>(static_cast<cv void*>(v)) nếu cả hai T1 và T2 là kiểu bố cục tiêu chuẩn (3.9) và yêu cầu căn chỉnh của T2 không chặt chẽ hơn so với T1, hoặc nếu một trong hai loại bị vô hiệu.

+0

Cảm ơn, đã sửa bản sao kê khai bị thiếu. – TemplateRex

+2

Điều đó không vi phạm nghiêm ngặt răng cưa? – Puppy

+0

@DeadMG: Tôi không chắc chắn. Tôi đã xem qua [một số phần trong tiêu chuẩn gây ra bí danh nghiêm ngặt] (http://stackoverflow.com/a/9588075/734069), và điều này dường như không vi phạm chúng. Nhưng tôi không phải là một chuyên gia về nó. –

Các vấn đề liên quan