Funkcje zaprzyjaźnione a przeciążanie operatorów

0

Witam!
Nurtuje mnie ostatnio przeciążanie operatorów poprzez metody klasy i funkcje zaprzyjaźnione. Otóż np mamy takie metody w klasie:

class Da {
...
public:
   Da operator*(double zmienna) const;
   friend Da operator*(double zmienna, const Da & obiekt) const;
};

Jest to mnożenie danych obiektu przez liczbę double.
Ogólnie powiem tyle - nie lubię niejasności i czytania między wierszami. A tutaj pierwsza metoda klasy jest właśnie taką niejasną, gdyż pierwszy parametr jest przekazywany niejawnie. Czy da się przeciążyć operator mnożenia dwoma funkcjami zaprzyjaźnionymi, takimi, jak np. tutaj?

class Da {
...
public:
   friend Da operator*(const Da & obiekt, double zmienna) const;
   friend Da operator*(double zmienna, const Da & obiekt) const;
};

Kod wtedy jest czytelniejszy, ale czy takie coś jest możliwe?

I mam jeszcze jedno pytanie - czy taką operację mnożenia można wykonać bez funkcji zaprzyjaźnionej? Np. tak:

class Da {
...
public:
  Da operator*(double zmienna) const;
  Da operator*(double zmienna, const Da & obiekt) const { return obiekt * zmienna; }
};

Wiem, że pytania mogą wydać się jakieś dziwne dla zaprawionych programistów, ale każdy miał swoje początki :) Chyba nie pomyliłem działów?

0

Kod wtedy jest czytelniejszy, ale czy takie coś jest możliwe?
A jaki to problem dać kompilatorowi i sprawdzić?

#include <iostream>
using namespace std;

class Da
{
    double czynieda;
    friend Da operator*(const Da& obiekt, double zmienna);
    friend Da operator*(double zmienna, const Da& obiekt);	
};

Da operator*(const Da& obiekt, double zmienna)
{
	Da da;
	da.czynieda = -111;
	return da;
}

Da operator*(double zmienna, const Da& obiekt)
{
	Da da;
	da.czynieda = 222;
	return da;
}

int main() 
{
	Da foo = Da() * 42.1;
	Da boo = 442.1 * Da();

	return 0;
}

Przy czym:

  1. Funkcja zaprzyjaźniona nie jest metodą klasy, więc nie może mieć kwalifikatora const.

Generalnie jak masz a * b, to to się rozwinie albo do

a.operator*(b)

albo

operator*(a, b)

Teraz jeśli przeciążasz operator za pomocą metody klasy, to będzie to pierwsze forma, czyli ta metoda musi przyjąć 1 argument. Więc takie coś nie przejdzie

Da operator*(double zmienna, const Da & obiekt) const { return obiekt * zmienna; }

jeśli to jest metoda klasowa, natomiast bez problemu przejdzie jeśli to jest zewnętrzna funkcja (oczywiście bez const - patrz wyżej).

1 użytkowników online, w tym zalogowanych: 0, gości: 1