2012-09-18 24 views
6

thể trùng lặp:
why private value of the obj can be changed by class instance?Tại sao == quá tải có thể truy cập các thành viên tư nhân của các đối số

Hãy xem xét những điều sau đây (một phần) mã:

class Group { 
    private: 
     int id; 

    public: 
     void set_id(int); 
     int get_id(); 
     bool operator==(const Group&); 
}; 


bool Group::operator==(const Group& g) { 
    if(g.id == this->id) { /* id is private? */ 
      return true; 
    } 

    return false; 
} 

mã biên dịch và kết quả có vẻ phù hợp. Tuy nhiên, trong phần if của việc thực thi quá tải toán tử, chúng tôi đang truy cập trực tiếp vào thành viên riêng tư của đối số của nó - const Group& g, nhưng không phải là truy cập không hợp lệ?

+1

Có gì sai với 'trở g.id == this-> id'? – sbi

+1

Trên một mặt lưu ý, tôi nghĩ tên người dùng "WeaklyTyped" khớp với câu hỏi này rất độc đáo. – datenwolf

+1

@sbi - nó có một 'this-> 'không cần thiết. –

Trả lời

16

operator== là thành viên của lớp học Group của bạn. Các hàm thành viên có thể truy cập bất kỳ thành viên private nào của lớp đó, không chỉ cho this, mà còn cho bất kỳ trường hợp nào họ có thể truy cập. Nếu bạn nghĩ về hành vi này là cần thiết, bởi vì nếu không thì điều khiển truy nhập sẽ làm cho các phương thức tương tác của hai hoặc nhiều trường hợp (swap, sao chép các nhà xây dựng, nhà khai thác) không thể, trừ khi đối tượng có một truy cập công khai đến bất kỳ biến thành viên nào, được sử dụng trong một phương pháp như vậy. Thường thì điều đó không được mong muốn từ quan điểm thiết kế. Hơn nữa, nó sẽ tăng thanh để kiểm soát truy cập đến cao ("nếu tôi chỉ đơn giản là làm cho thành viên đó công khai, tôi có thể tha cho tôi nỗi đau ...").

Kết mã này là hoàn toàn hợp lệ (mặc dù tôi không hiểu tại sao các if là cần thiết, so với chỉ đơn giản là sử dụng return g.id == this->id;)

+0

Cảm ơn! Để giải thích. – WeaklyTyped

5

Không, bởi vì operator== là thành viên của Group. Nó ở ngay trong tên hàm. Điều đó có nghĩa là nó có thể truy cập các thành viên private của bất kỳ đối tượng nào của lớp đó.

Nếu bạn đã cố gắng để viết nó như một chức năng miễn phí, mà sẽ không có biên soạn: vòng loại

bool areEqual(const Group& g1, const Group& g2) { 
    return g1.id == g2.id; 
} 
13

truy cập không được kiểm soát truy cập vào mức độ chẳng hạn, nhưng về mức độ loại. Bất kỳ hàm thành viên nào của một thể hiện kiểu T đều có thể truy cập tất cả các thành viên riêng của bất kỳ cá thể nào khác thuộc cùng một kiểu T.

operator== là một hàm thành viên, nó có thể truy cập tất cả các biến thành viên của lớp đó. thành viên của.

+0

Tôi nhận được quan điểm của bạn, nhưng tôi thực sự đánh giá cao nếu bạn có thể chỉ ra tại sao các specifier hoạt động ở Type Level chứ không phải mức instance? Có phải là một lý do. – WeaklyTyped

+1

@WeaklyTyped nếu chúng không hoạt động ở cấp loại, bạn sẽ không thể sao chép cấu trúc hoặc gán trừ khi tất cả dữ liệu được công khai hoặc có "getters" cho mọi thành viên dữ liệu. – juanchopanza

+0

@WeaklyTyped: Vì C++ là một ngôn ngữ được kiểm tra kiểu tĩnh và không thể xác định tĩnh nếu truy cập vẫn còn trong cá thể (Sự cố dừng).Lấy ví dụ hàm thành viên 'class T {private: int bar; public: void foo (T * t) {t * = t-> bar;} void spam() {foo (this);} '- foo có thể được gọi từ hoặc là" bên ngoài "lớp hoặc từ bên trong bằng cách sử dụng' con trỏ này. Tại thời gian biên dịch, không thể kiểm tra tĩnh nếu điều này xảy ra hay không. Ngoài ra những gì juanchopanza nói. – datenwolf

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