Verder lezen:
In codevoorbeeld 06-04 moeten we voor het optellen van twee locaties twee statements gebruiken, één voor de x en één voor de y.
class vector {
public:
int x;
int y;
. . .
};
vector a( 1, 2 ), b( 3, 4 );
// add b to a
a.x += b.x;
a.y += b.y;
Codevoorbeeld 06-04 (herhaald)- Vectoren bij elkaar optellen via publieke attributen
We kunnen dit makkelijker maken, want in C++ zijn operatoren zoals +
eigenlijk gewoon methoden (klasse functies). Als een passende operator+
is gedeclareerd zijn de volgende twee expressies legaal in C++ en betekenen exact hetzelfde:
a + b a.operator+( b )
Codevoorbeeld 06-05 - Twee manieren om dezelfde operator+ methode aan te roepen
Als we twee locaties bij elkaar op willen kunnen tellen dan moeten we daar de passende operator+
voor schrijven.
class vector {
public:
int x;
int y;
. . .
vector operator+( const vector & rhs ) const {
return vector( x + rhs.x, y + rhs.y ); }
};
vector a( 1, 2 ), b( 3, 4 );
// calculations with vectors
a = a + b;
Codevoorbeeld 06-06 - Een operator+ maken
De operator+
heeft twee parameters van het type vector: de eerste (linker) parameter is het object zelf, de tweede (rechter) is hier rhs (Right Hand Side) genoemd. De rhs parameter wordt overgedragen by reference (de &
), en meer specifiek by const
reference: de operator+ belooft plechtig dat hij die parameter niet zal wijzigen, en de compiler zal hem daaraan houden. Daardoor kan de operator ook aangeroepen worden met als argument een constante of een expressie.
Behalve voor ingebouwde operatoren typen (bv. int); daarvoor is alleen de a + b schrijfwijze toegestaan.
Een + is symmetrisch, dus we willen dat de lhs (Left Hand Side, het object zelf dus) ook ‘by const reference’ moet worden overgedragen, maar die lhs zit niet in de parameter lijst, dat is het object zelf. Dit object wordt (als er niets anders is aangegeven) in feite ‘by reference’ overgedragen: de functies van de klasse kunnen de variabelen in het object lezen en schrijven. Als we willen dat de functies van de klasse de variabelen van de klasse kunnen lezen maar niet schrijven, dan moeten we het object ook als ‘const’ markeren. Volgens de C++ syntax moet dat meteen ná de parameterlijst (voor de {
open-krulhaak).
De body van de operator is bijna triviaal: het resultaat van de functie is een waarde van het type vector
. Die waarde construeren we door de vector constructor aan te roepen met de juiste x en y waarden.
Behalve de tweezijdige (diadic) + is er ook een eenzijdige (monadic) +. Dit is een veel minder nuttige operator, die er eigenlijk alleen is omdat de eenzijdige - wél een nuttige operator is. De eenzijdige operatoren hebben geen rhs (de enige parameter is het object zelf, dat impliciet wordt doorgegeven), dus hun parameterlijst is leeg.
class vector {
public:
int x;
int y;
. . .
vector operator+() const {
return vector( x, y );
}
};
vector a( 1, 2 ), b( 3, 4 );
a = + b;
Codevoorbeeld 06-07 - Een eenzijdige (monadic) operator+
Vector is natuurlijk niet het enige data type waarvoor je een optel-operator zou willen hebben. (En met de diadic en monadic operatoren heeft vector er al twee!) Dat leidt er toe dat er veel operator+ functies kunnen zijn. In C++ is het geen probleem als er meerdere functies met dezelfde naam zijn, mits de compiler bij iedere aanroep van een functie aan het aantal en de typen van de parameters kan zien welke functie er wordt aangeroepen.
In het volgende stukje code worden drie + operatoren aangeroepen.
vector
dus de aangeroepen functie is de zojuist beschreven ( vector + vector
).int
, dus de aangeroepen functie is de ingebouwde ( int + int
) operator.vector
en int
. Tenzij iemand een dergelijke functie gemaakt heeft zal de compiler hier een foutmelding geven omdat hij geen passende operator+ kan vinden.vector a( 1, 2 ), b( 3, 4 ), c( 5, 6 );
int x = 1, y = 2, z;
c = a + b; // vector + vector
z = x + y; // int + int
z = x + b; // compilation error (geen int + vector)
Codevoorbeeld 06-08 - Drie verschillende + operatoren naast elkaar
Functies met dezelfde naam worden ‘overloaded’ genoemd. Overloading is in C++ mogelijk voor alle functies en methoden. Het wordt veel gebruikt bij operatoren en bij constructors.
In C is overloading niet mogelijk, daar moet iedere functie een unieke naam hebben.