czy można podaną funkcje przerobić aby nie było friend
friend ostream & operator << (ostream & s, const zesp & c)
{
s << "(" << c.real << "," << c.imag << ")";
return s;
}
struct zesp { double real,imag; };
i już wystarczy nie musi być friend;
Lub:
class zesp
{
private:
double real,imag; // właściwie to dziwne dla tej klasy, te składowe nie trzeba hermetyzować.
...
ostream &out(ostream &s)const { return s<<'('<<real<<','<<imag<<')'; }
};
inline ostream &operator<<(ostream &s,const zesp &z) { return z.out(s); }
to jest całkowicie uzasadnione użycie friend
, dlaczego chcesz kod komplikować dla głupiej zasady?
friend ostream & operator << (ostream & s,const zesp & c)
{
s << "(" << c.real << "," << c.imag << ")";//odpowiada za wyswietlanie wynikow
return s;
}
W tym jest taki myk że :
s << "(" << c.real << "," << c.imag << ")";
jest odpowiedzialne za wyświetlanie wyników w main
i na struct nie działało :(
Jeżeli nie masz getterów/setterów to powinieneś użyć friend
. Jeżeli je masz to ich użyj.
Niektórzy będą się upierać, że nie ma po co robić tych getterów (tylko wsadzić to w public
), niektórzy będą się upierać, że należy zawsze. A moim zdaniem to kwestia stylu, bo niczego innego to nie zmienia dla tak prostych przypadków. Zasadniczo największy sens one mają, kiedy należy w jakiś sposób kontrolować zapis czy odczyt. Ale można po prostu robić to zawsze dla zachowania spójności - taka funkcja inline
i tak będzie działać tak, jakby jej nie było (w absolutnie każdym normalnym kompilatorze, poza kompilatorem @_13th_Dragon, ale on używa do tego celu worka ziemniaków i nie należy się jego opiniami przejmować ;-), tylko więcej pisania troszkę ale i teoretycznie więcej miejsca na błędy.
A czy można było by
friend ostream & operator << (ostream & s,const zesp & c)
{
s << "(" << c.real << "," << c.imag << ")";//odpowiada za wyswietlanie wynikow
return s;
}
przerobić na Void ?? albo jakoś inaczej , tak aby nie było Friend :)- zaprzyjaźniania klas :(
zest z; cout<<z;
- zadziała, zaś zest z; cout<<z<<endl;
- już nie.
IMO operatory nigdy nie powinny skomplikowanego kodu, ale zawsze powinny mieć jedną klinikę z wywołaniem normalnej funkcji, która robi to co oczekujemy od operatora. W podanym przypadku powinno być tak:
class zesp {
...
ostream & wypiszDoStrumienia(ostream & s) {
s << "(" << real << "," << imag << ")";
return s;
}
};
ostream & operator << (ostream & s, const zesp & c) {
return c.wypiszDoStrumienia(s);
}
Zalet jest wiele. Nie trzeba bawić się w przyjaźnie, łatwiej utrzymywać kod z takim operatorem, a w przypadku bibliotek łatwiej poprawić te operatory nie psując binary/code compatibility.
std::ostream& zesp::out(std::ostream&) const’ is private