30/09/2018, 20:24 
               
            Thắc mắc nạp chồng toán tử input/output c++
Giả sử có 1 lớp phân số. khi nạp chồng operator <<, >> thì hầu như đều sử dụng hàm friend (2 đối số):
friend ostream& operator<<( ostream& os,phanso &ps);
friend istream& operator>>( istream& is,phanso &ps);
Nhưng e thắc mắc là nếu ta không dùng hàm bạn thì có được không? Nếu k dùng hàm bạn thì phải viết như thế nào ạ? Ai giúp e với
            Bài liên quan
         
                
            




Oh bạn overloading
<<và>>thì không thể dùngmember functionđược mà phải dùngnon-member functionnhé vì<<và>>là stream operator.giải thích cụ thể cho e được k ạ? e mới tự học nên chưa rõ ạ
huhm, chắc bạn đang học C++ và học tới bài
friendnên có ví dụ này đúng không. Bạn tự code (và tìm hiểu) rồi thắc mắc chỗ nào đưa lên cụ thể, mình sẽ giải thích rõ hơn.nói chính xác hơn là
<<và>>là toán tử dịch bit. Lão Stroustrup bị khùng nên lấy toán tử dịch bit đi làm input output cho stream.<<và>>thì cũng như phép+hay-, có 2 phần tử tham gia: vế trái và vế phải. Viết 1 hàm cho toán tử có thể viết theo công thức<kiểu trả về> operator<toán tử>(<kiểu vế trái> <vế trái>, <kiểu vế phải> <vế phải>);ví dụ
std::ostream& operator<<(std::ostream& out, const PhanSo& rhs);thì kiểu trả về là
std::ostream&toán tử là
<<kiểu vế trái là
std::ostream&(trùng với kiểu trả về)kiểu vế phải là
const PhanSo&thì khi sử dụng
<<trong câu lệnhstd::cout << ps;vế trái làstd::coutcó kiểu kế thừa từstd::ostreamnên có thể xem làstd::ostream, vế phải làpscó kiểu làPhanSođược truyền const-reference vào<<tức là truyền đích thịpschứ ko tạo ra bản copy, vào bản chính truyền vào được xem như là 1 hằng.vì sao kiểu trả về trùng với kiểu vế trái: để có thể viết như vầy:
std::cout << ps1 << "\n";Toán tử<<được xét từ trái sang phải, tức làstd::cout << ps1 << "\n";được xét(std::cout << ps1) << "\n";Như vậy kết quả trả về của(std::cout << ps1)sẽ là vế trái của toán tử<<tiếp theo, vì vậy nên trả về trùng kiểu vế trái của toán tử trước nó.phương thức (hàm của class) thì vế trái luôn luôn có kiểu là
T*(T là tên của class) hoặcconst T*nếu thêmconstvào phía sau khai báo của phương thức. Tức là con trỏthisluôn được xem là vế trái của 1 phương thức trong class.vì
<<là operator cho stream nên vế trái của nó ở đây làstd::ostreamchứ ko phảiPhanSo, vì vậy phải viết hàm ko thuộc class. (hàm thuộc class gọi là phương thức, hàm ko thuộc class nào gọi là… hàm). Nhưng vì hàm nằm ngoài class ko thể truy cập các phần tửprivatecủa class (ở đây là tử số và mẫu số) nên lão Stroustrup chế ra cái keywordfriendtức là hàm này có quyền truy cập các phần tửprivatecủa class thoải mái, miễn là có khai báofriend <khai báo hàm>trong class (bạn bè có quyền lục lọi đồ riêng tư của bạn bè? Chọn tên cũng khùng vãi )vì
friendđơn giản là phá hủy tính đóng gói (encapsulation), 1 trong các quy tắc của OOP, nên hạn chế xàifriend.Không liên qua đến toán tử shift bit bạn nhé, dù cho nó có giống nhau về mặt hình thức. Cái này là kế thừa từ toán tử in/out của Unix.
friendkhông phá hủy tính đóng gói,friendnâng cấp tính đóng gói.phá hủy đó. Đóng gói tức là hiding data, tức là che dữ liệu lại bằng private hay protected, friend nó lờ đi hết 2 thứ đó thì phá hủy chứ nâng cấp gì ở đây.
Encapsulation không phải là Hiding Data, đừng đánh đồng.
Bạn đang đứng ở view Friend không thuộc class. Friend phải được coi là một phần của class, giúp mở rộng phạm vi của interface của class ra nên nó nâng cấp sự Encapsulation chứ không phải phá hủy.
Java, C# đâu có
friendđâu, C++ đã làm class rồi lại thích trở về C struct nên mới có cái vụ friend này. OOP nói chung chả cần khái niệm friend làm gì. C++ thì nổi tiếng thích ôm đồm nhiều thứ nên mới có cái rắc rối như vậy.Về việc James Gosling không thêm keyword
friendvào Java thì mình không đủ tư cách để phán xét. Nhưng rất nhiều trường hợp người viết Java phải hiện thực code theo hình thái củafriendvì thấy nó hữu dụng, chẳng hạn trong Unit Testing.Việc thêm
friendtrong C++ hoàn toàn không liên quan đến C struct. C++ và C là hai ngôn ngữ riêng rẽ.C++ ôm đồm hay không thì mình cũng không dám phán xét luôn
Về vấn đề ôm đồm thì Đạt cùng ý kiến với @tntxtnt, C++ ôm đồm nhiều thứ quá. C++ không phải “chỉ là” hướng đối tượng
Why C++ is not just an Object-Oriented Programming Language
Chính xác, C++ chưa bao giờ “chỉ là ngôn ngữ hướng đối tượng” cả
Em vẫn còn một thắc mắc là friend có tác dụng giúp hàm truy cập các phần tử private nhưng mà theo em đã biết thì những hàm trong public thuộc class đó vẫn truy cập được phần tử private mà. Em mới học class được 3 ngày. Mong các anh chỉ giáo ạ
Hàm thuộc class đó nó vẫn nằm trong class đó, những gì bên ngoài mới không tác động được, kể cả class con
Protected thì class con có thể tác động được.
Bạn nên học lại khái niệm về 3 thằng public/protected/private
Cái friend nó cũng khai báo trong class mà anh/chị.