Giriş
C++'ta kullanılabilen Arithmetic Operators toplam 10 tane.
1.Assignment,
2.Addition,
3.Subtraction,
4.Unary Plus,
5.Unary Minus,
6.Multiplication,
7.Division,
8.Modulo,
9.Postfix Increment, Prefix Increment,
10.Postfix Decrement, Prefix Decrement
1. Genel Konular
1.1 Arithmetic Operator Metodun Global Veya Üye Metod Olması
Her ikisi de olabilir.
1.2 Arithmetic Operator Metodun Virtual Olması
Bütün metodlar gibi bu operatörler istenirse virtual olabiliyorlar.
1.3 Arithmetic Operator Metodun Bir Sonuç Dönmesi
Şart değil. Şöyle yaparız
Gördüğüm en ilginç kodlardan birisi. Önce bir Pow tanımlanır.
Şimdi her bir Arithmetic Operator metodlarına teker teker bakalım
2.2. Addition Operator
Açıklaması şöyle.
Global Metod Olarak Tanımlama
Bu operator bir sürü farklı şekilde tanımlanabilir. Global metod parametrelerden birisi class olmadığı için şu şekilde olamaz.
Şöyle yaparız.
Global metod genelde friend tanımlanır ki sınıfın içindeki private alanlara erişebilsin.
Örnek
Şöyle yaparız.
2. kullanım şekli makul ancak parametre ve metod imzası const değil. const olsa daha iyi.
3. kullanım şekli en klasik olanı. Bu kullanımda a = b + c işlemi rahatlıkla yapılabiliyor.
4. ve 5. kullanım şeklide ise gereksiz kopyalama olduğu için tercih edilmemeli.
Örnek
Şöyle yaparız.
Operatorden virtual metod çağırabiliriz. Böylece sol taraf kalıtan sınıfsa daha özel bir işlem yapabiliriz.
2.4. Unary Minus
Değeri eksi haline çevirir. -a gibi düşünülmelidir. Metodun imzası şöyle. Temporary bir nesne döndürür.
İskeleti şöyledir.
C++ ve Çoklu Prefix Increment
C++ ve C arasında bazı farklar var. Şu kod C++'ta derlenir. C'de ise derlenmez.
İskeleti şöyledir.
C++'ta kullanılabilen Arithmetic Operators toplam 10 tane.
1.Assignment,
2.Addition,
3.Subtraction,
4.Unary Plus,
5.Unary Minus,
6.Multiplication,
7.Division,
8.Modulo,
9.Postfix Increment, Prefix Increment,
10.Postfix Decrement, Prefix Decrement
1. Genel Konular
1.1 Arithmetic Operator Metodun Global Veya Üye Metod Olması
Her ikisi de olabilir.
1.2 Arithmetic Operator Metodun Virtual Olması
Bütün metodlar gibi bu operatörler istenirse virtual olabiliyorlar.
1.3 Arithmetic Operator Metodun Bir Sonuç Dönmesi
Şart değil. Şöyle yaparız
#include <iostream>
struct foo {
void operator+(int x) {
std::cout << x;
}
};
int main () {
foo f;
f + 3;
}
1.4 Named OperatorGördüğüm en ilginç kodlardan birisi. Önce bir Pow tanımlanır.
const struct PowOperator {} Pow;
struct PowInvoker
{
int lhs;
};
PowInvoker operator< (int lhs, PowOperator)
{
return {lhs};
}
int operator> (PowInvoker lhs, int rhs)
{
return std::pow(lhs.lhs, rhs);
}
int main()
{
std::cout << (2 <Pow> 3) << std::endl;
}
Sonra kod şöyle çağrılır.std::cout << (2 <Pow> 3) << std::endl;
2. Operator MetodlarıŞimdi her bir Arithmetic Operator metodlarına teker teker bakalım
2.2. Addition Operator
Açıklaması şöyle.
Diğer operator metodlarında olduğu gibi ya bir member metod ya da global bir metod tanımlamak gerekir. Her iki yöntem de rvalue dönmelidir ve const olmalıdır.A binary operator can be overloaded as a non-static member function with one parameter or as a non-member function with two parameters (one of those parameters must be either a class object or a reference to a class object).
Global Metod Olarak Tanımlama
Bu operator bir sürü farklı şekilde tanımlanabilir. Global metod parametrelerden birisi class olmadığı için şu şekilde olamaz.
int operator+(int, int);
ÖrnekŞöyle yaparız.
Foo operator+(Foo , int);
Foo operator+(Foo& , int);
Foo operator+(int, Foo);
Foo operator+(int, Foo&);
ÖrnekGlobal metod genelde friend tanımlanır ki sınıfın içindeki private alanlara erişebilsin.
class matrix
{
public:
friend matrix operator+(const matrix &, const matrix &);
};
matrix operator+(const matrix &, const matrix &);
Üye metod Olarak Tanımlama
Bu operator bir sürü farklı şekilde tanımlanabilir.Örnek
Şöyle yaparız.
ClassName & operator+(ClassName &other)
ClassName operator+(ClassName &other)
Classname operator+(const ClassName &other) const
Classname operator+(const Classname other)
Classname operator+(Classname other)
1. tanımlama referans döndürdüğü için iyi değil. a = b +c hata yapmaya açık hale geliyor.2. kullanım şekli makul ancak parametre ve metod imzası const değil. const olsa daha iyi.
3. kullanım şekli en klasik olanı. Bu kullanımda a = b + c işlemi rahatlıkla yapılabiliyor.
4. ve 5. kullanım şeklide ise gereksiz kopyalama olduğu için tercih edilmemeli.
Örnek
Şöyle yaparız.
class matrix
{
public:
matrix operator+(const matrix &) const; // member version
};
ÖrnekOperatorden virtual metod çağırabiliriz. Böylece sol taraf kalıtan sınıfsa daha özel bir işlem yapabiliriz.
struct Base {
Base operator+(const Base& other) {
return add(other);
}
protected:
virtual Base add(const Base& other) {
cout << "Adding in Base's code." << endl;
return Base();
}
};
struct Derived : public Base {
protected:
virtual Base add(const Base& other) {
cout << "Adding in Derived's code." << endl;
return Derived();
}
};
int main() {
Base b1;
Base b2;
Derived d1;
Derived d2;
Base res;
res = b1+b2; // Prints "Adding in Base's code."
res = b1+d2; // Prints "Adding in Base's code."
res = d1+b2; // Prints "Adding in Derived's code."
res = d1+d2; // Prints "Adding in Derived's code."
return 0;
}
2.4. Unary Minus
Değeri eksi haline çevirir. -a gibi düşünülmelidir. Metodun imzası şöyle. Temporary bir nesne döndürür.
MyClass operator -(MyClass& u)
2.9. Prefix Incrementİskeleti şöyledir.
typename& typename::operator++()
{
// Change state
...
// Return the object
return *this;
}
Şöyle yaparız.Foo& Foo::operator++() // called for ++i
{
this->data += 1;
return *this;
}
Prefix Increment ile ilgili bir açıklama şöyle.Hız açısından normalde prefix increment, postfix increment'e tercih edilir. Çok nadir durumlarda prefix increment postfix increment'e tercih edilmez. Elimizde şöyle bir kod olsun.preincrement introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression."
a = b++ * 2;
Bu kod paralel çalıştırılabilir çünkü çarpma işleminin gerçekleşmesi için b'nin postfix increment işleminin bitmesini beklemeye gerek yoktur. Ancak kod şöyle olsaydıa = ++b * 2;
Bu kod paralel çalıştırılamazdı, çünkü çarpma işleminin gerçekleşmesi için önce b'nin prefix increment işleminin bitmesi gerekirdi.C++ ve Çoklu Prefix Increment
C++ ve C arasında bazı farklar var. Şu kod C++'ta derlenir. C'de ise derlenmez.
int main()
{
int i = 0;
++++i;
}
2.10. Postfix Incrementİskeleti şöyledir.
typename typename::operator++(int)
{
// Create a temporary object that is a copy of the current object.
typename temp(*this):
// Change state of the current object
...
// Return the temporary object.
return temp;
}
Yeni bir kopya yaratır. Şöyle yaparız.Foo Foo::operator++(int ignored_dummy_value) // called for i++
{
Foo tmp(*this); // variable "tmp" cannot be optimized away by the compiler
++(*this);
return tmp;
}
Hiç yorum yok:
Yorum Gönder