Jika memungkinkan, sebagai fungsi non-anggota dan non-teman.
Seperti yang dijelaskan oleh Herb Sutter dan Scott Meyers, lebih memilih fungsi non-teman bukan anggota daripada fungsi anggota, untuk membantu meningkatkan enkapsulasi.
Dalam beberapa kasus, seperti streaming C ++, Anda tidak memiliki pilihan dan harus menggunakan fungsi non-anggota.
Namun tetap saja, itu tidak berarti Anda harus menjadikan fungsi-fungsi ini sebagai teman kelas Anda: Fungsi-fungsi ini masih dapat mengakses kelas Anda melalui pengakses kelas Anda. Jika Anda berhasil menyusun fungsi tersebut dengan cara ini, maka Anda menang.
Tentang prototipe operator << dan >>
Saya yakin contoh yang Anda berikan dalam pertanyaan Anda salah. Sebagai contoh;
ostream & operator<<(ostream &os) {
return os << paragraph;
}
Saya bahkan tidak bisa mulai memikirkan bagaimana metode ini bisa bekerja dalam aliran.
Berikut adalah dua cara untuk mengimplementasikan operator << dan >>.
Katakanlah Anda ingin menggunakan objek seperti aliran tipe T.
Dan Anda ingin mengekstrak / menyisipkan dari / ke dalam T data yang relevan dari objek Anda berjenis Paragraph.
Operator generik << dan >> prototipe fungsi
Yang pertama sebagai fungsi:
// T << Paragraph
T & operator << (T & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// T >> Paragraph
T & operator >> (T & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return p_oInputStream ;
}
Prototipe metode << dan >> operator generik
Yang kedua sebagai metode:
// T << Paragraph
T & T::operator << (const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return *this ;
}
// T >> Paragraph
T & T::operator >> (const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return *this ;
}
Perhatikan bahwa untuk menggunakan notasi ini, Anda harus memperluas deklarasi kelas T. Untuk objek STL, ini tidak dimungkinkan (Anda tidak seharusnya memodifikasinya ...).
Dan bagaimana jika T adalah aliran C ++?
Berikut adalah prototipe dari operator << dan >> yang sama untuk aliran C ++.
Untuk basic_istream dan basic_ostream generik
Perhatikan bahwa ini adalah kasus streaming, karena Anda tidak dapat mengubah aliran C ++, Anda harus mengimplementasikan fungsinya. Artinya seperti:
// OUTPUT << Paragraph
template <typename charT, typename traits>
std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> Paragraph
template <typename charT, typename traits>
std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & p_oInputStream, const CMyObject & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
Untuk char istream dan ostream
Kode berikut hanya akan berfungsi untuk aliran berbasis karakter.
// OUTPUT << A
std::ostream & operator << (std::ostream & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> A
std::istream & operator >> (std::istream & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
Rhys Ulerich berkomentar tentang fakta bahwa kode berbasis char hanyalah "spesialisasi" dari kode generik di atasnya. Tentu saja, Rhys benar: Saya tidak merekomendasikan penggunaan contoh berbasis karakter. Ini hanya diberikan di sini karena lebih mudah dibaca. Karena ini hanya dapat dijalankan jika Anda hanya bekerja dengan aliran berbasis char, Anda harus menghindarinya pada platform di mana kode wchar_t umum (misalnya pada Windows).
Semoga ini bisa membantu.