2010-03-21 38 views
5

Tôi thấy điều này từ C++ Hỏi đápTôi có nên trỏ từ một lớp dẫn xuất riêng đến lớp cơ sở của nó không?

Nói chung, số

Từ một hàm thành viên hoặc bạn bè của một lớp tư nhân có nguồn gốc, mối quan hệ đến lớp cơ sở được được biết đến, và chuyển đổi trở lên từ PrivatelyDer * đến Base * (hoặc PrivatelyDer & tới Base &) là an toàn; không cần số diễn xuất hoặc được đề xuất.

Tuy nhiên người sử dụng PrivatelyDer nên tránh chuyển đổi không an toàn này, vì nó được dựa trên một quyết định riêng của PrivatelyDer, và có thể thay đổi mà không cần báo .

Làm cách nào để hiểu các từ trên? Tôi không nghĩ lời giải thích là chính xác hay chính xác.

Tôi có một mã như thế này

class A{ 
}; 

class B: private A{ 
}; 

int main(){ 

    B *b = new B(); 
    A *a = new A(); 

    a = b;     //wrong 
    a = (A*)b;   //right 

} 
+2

Các diễn viên tiềm ẩn không biên dịch (A là cơ sở không thể tiếp cận), và một trong những thứ hai sử dụng một dàn diễn viên C-phong cách, đó là tương đương của 'reinterpret_cast' đây? – UncleBens

+0

có bạn nói đúng, diễn giải lại diễn viên là điều ác như chúng ta đều biết. những gì ông đã làm trong dòng cuối cùng không phải là một thực hành tốt –

Trả lời

4

Từ quan điểm thuần túy cơ học, bạn nói đúng: một diễn viên vào một lớp cơ sở riêng sẽ hoạt động và tạo ra kết quả làm việc.

Điểm của Câu hỏi thường gặp là từ quan điểm thiết kế, thường thì sai. Sự thừa kế riêng tư thực sự có nghĩa là riêng tư - nói cách khác, mặc dù nó có thể hoạt động, bạn không được phép biết nó sẽ hoạt động, và tại một thời điểm nào đó nó có thể ngừng hoạt động - vì nó chính thức là chi tiết thực hiện, chứ không phải một phần của giao diện công khai, họ có thể triển khai lại lớp mà không cần sử dụng thừa kế. Tại thời điểm đó, dàn diễn viên sẽ không hoạt động nữa (nhưng vì bạn đã sử dụng dàn diễn viên, trình biên dịch có thể sẽ không cảnh báo bạn về việc đã chuyển từ thứ gì đó mà bạn có thể không làm cho một thứ không thể hoạt động ở tất cả).

Chỉnh sửa: Có, dàn diễn viên không nhất thiết phải hoạt động. Theo §5.4/7 của tiêu chuẩn:

...các static_cast sau và hoạt động reinterpret_cast (tùy chọn theo sau là một const_cast hoạt động) có thể được thực hiện bằng cách sử dụng ký hiệu diễn viên của rõ ràng chuyển đổi loại , ngay cả khi lớp cơ sở loại không thể truy cập:

- một con trỏ tới một đối tượng có nguồn gốc từ loại có nguồn gốc hoặc một giá trị của loại có nguồn gốc có thể được chuyển đổi một cách rõ ràng thành con trỏ hoặc tham chiếu đến loại cơ sở không rõ ràng , ;

[nhấn mạnh thêm]

+0

Không, dàn diễn viên sẽ không nhất thiết phải hoạt động. –

+0

Đúng, đã học được điều gì đó mới mẻ ngày hôm nay. :-) –

+0

@Konrad: một trong những thời gian hiếm hoi mà tôi không chắc là học được điều gì đó mới là một điều tuyệt vời! Tôi gần như ước mình không biết, bởi vì sẽ không có cám dỗ khi sử dụng nó. :-) –

1

Tôi nghĩ rằng lời giải thích là đúng. Nó nói rằng mặc dù một diễn viên là có thể từ B đến A nó không nên được thực hiện. Reasone là thừa kế là riêng và nên được coi là chi tiết triển khai của B mà người dùng của lớp sẽ không bao giờ quan tâm. Nó chỉ là các quy tắc tương tự như bất cứ điều gì được đánh dấu private - nó phải được coi là nội bộ cho lớp. Khách hàng bên ngoài chỉ nên dựa vào các hàm và thuộc tính public - bao gồm cả thừa kế public.

Cá nhân tôi chưa bao giờ tìm thấy bất kỳ việc sử dụng nào để thừa kế riêng tư - tôi nghĩ rằng thường tốt hơn khi sử dụng bố cục.

+0

@Anders: thừa kế riêng có ý nghĩa khi kết hợp với các lớp chính sách (chẳng hạn như 'std :: allocator'): các lớp như vậy thường trống. Có họ như là thành viên tư nhân vẫn sẽ tiêu thụ bộ nhớ bởi vì mọi thành viên của một lớp phải có một địa chỉ riêng biệt, ngay cả khi thành viên không cần bộ nhớ. Thừa kế từ chúng, tuy nhiên, sẽ * không * tiêu thụ bộ nhớ không cần thiết. –

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