I ja se ne slazem sa djoka_I.
Evo primera gde Non-Member friend funkcije mogu da pomognu:
Recimo da imamo klasu koja ima int kao member i zelimo da sabiramo tu klasu sa obicnom int promenljivom:
Code:
class SomeClass
{
int m_data;
public:
SomeClass(int data) : m_data(data) {}
// za slucaj 1. u main()
SomeClass operator+(int rhs)
{
return SomeClass(m_data + rhs);
}
// da bi slucaj 2. u main() radio moramo da implementiramo operator int()
/*
operator int() const
{
return m_data;
}
*/
};
int main()
{
SomeClass a(3);
SomeClass b = a + 3; ..... 1.
SomeClass c = 3 + a; ..... 2.
return 0;
}
Po meni, bolji nacin za ovo je:
Code:
class SomeClass
{
int m_data;
public:
SomeClass(int data) : m_data(data) {}
// ova funkcija moze da ostane kao u proslom primeru ali cu i nju napisati kao friend
friend SomeClass operator+(const SomeClass& sc, int a);
friend SomeClass operator+(int a, const SomeClass& sc);
};
SomeClass operator+(const SomeClass& sc, int a)
{
return SomeClass(sc.m_data + a);
}
SomeClass operator+(int a, const SomeClass& sc)
{
return SomeClass(sc.m_data + a);
}
int main()
{
SomeClass a(3);
SomeClass b = a + 3;
SomeClass c = 3 + a;
return 0;
}
Istina je da se ovim narusava enkapsulacija. Kod se moze poboljsati tako sto se moze obezbediti get() metoda za m_data i da se poziva getter umesto direktnog pristupa m_data promenljivoj u operator+() funkcijama ali ne mislim da je ovo losa praksa programiranja ako se primenjuje u prikladnim situacijama kao sto je ovaj primer.
Evo jos jednog primera.
Ako imamo klasu Element i iz nje izvedene Line, Circle itd. i zelimo da napravimo ogranicen mehanizam za kreaciju ovih objekata, u smislu da user ne moze direktno da pozove new za Line, Circle vec mora da koristi Factory, na primer, zato sto je za kreaciju objekta potrebno vise koraka koji se striktno moraju odraditi a ne zelimo da opteretimo klijenta ovih klasa tim detaljima, tada mozemo da stavimo da su konstruktori Line, Circle privatni a da Factory klasa bude friend klasama Line i Circle tako da samo Factory moze da pozove konstruktore klasa Line i Circle.
Advanced: Konkretna potreba za ovim bi bila u slucaju da se koristi shared_from_this() funkcija koja ne moze da se pozove dok objekat nije potpuno konstruisan pa posle toga mora da se pozove neka init() funkcija koja bi pozvala shared_from_this() da bi objekat, na primer, sam sebe dodao u neku listu. Ili u Qt, posle konstruisanja objekta da se objekat poveze pomocu signala/slotova sa drugim objektima.
[Ovu poruku je menjao glorius dana 20.11.2013. u 10:49 GMT+1]