Luồng đầu ra xử lý định dạng đầu ra cũng như đầu ra. Vì vậy, với phương pháp toString()
khách hàng của bạn sẽ không thể để quản lý các định dạng cho các đối tượng theo cách mà họ làm cho mọi thứ khác:
// set specific formatting options for printing a value
std::cout << std::scientific << std::setprecision(10) << 10.0 << '\n'; // prints 1.0000000000e+01
// set formatting based on user's cultural conventions
std::cout.imbue(std::locale(""));
std::cout << 10000000 << '\n'; // depending on your system configuration may print "10,000,000"
Có lẽ bạn không quan tâm để cho phép bất kỳ định dạng vì vậy có lẽ điều này sẽ không thành vấn đề .
Một lưu ý khác là xuất ra luồng không yêu cầu toàn bộ chuỗi biểu diễn nằm trong bộ nhớ cùng một lúc, nhưng phương thức toString()
của bạn.
Những người khác đã chỉ ra điều này, nhưng tôi nghĩ một cách rõ ràng hơn về nói rằng nó là giao diện các lớp học của bạn không chỉ giới hạn trong phương pháp nó cung cấp, mà còn bao gồm các chức năng khác mà bạn xây dựng xung quanh nó, bao gồm cả phi các hàm -member như quá tải operator<<
mà bạn cung cấp. Mặc dù nó không phải là một phương pháp của lớp học của bạn, bạn vẫn nên nghĩ về nó như là một phần của giao diện lớp học của bạn.
Dưới đây là một bài báo rằng cuộc đàm phán về vấn đề này mà có lẽ bạn sẽ thấy hữu ích: How Non-Member Functions Improve Encapsulation
Dưới đây là một ví dụ đơn giản của quá tải operator<<
cho một người sử dụng lớp định nghĩa:
#include <iostream>
struct MyClass {
int n;
};
std::ostream &operator<< (std::ostream &os, MyClass const &m) {
for (int i = 0; i < m.n; ++i) {
os << i << ' ';
}
return os;
}
int main() {
MyClass c = {1000000};
std::cout << c << '\n';
}
Làm thế nào bạn sẽ làm điều đó cho một 'int'? Hoặc bạn có nghĩa là 'to_string'? – doctorlove
Bởi vì làm cho một cái gì đó có thể stream được không giống như chuyển đổi nó thành một chuỗi. Nếu bạn muốn loại của bạn được streamable, quá tải 'ostream & operator <<'. Nếu bạn muốn tạo chuỗi từ nó, hãy cho nó một thành viên to_string. – juanchopanza