14 Aralık 2016 Çarşamba

Dönüşüm Operatörleri - Conversion Operators

Dönüşüm Operatörleri - Conversion Operator Nedir?
Dönüşüm operatörleri C++ dilinde Other Operators sınıfına dahil edilir. Bütün metodlar gibi bu operatörler istenirse virtual olabiliyorlar.

Dönüşüm operatörleri bence tamamen kafa karışıklığına sebep oluyorlar. Getter metodu kullanmak çok daha iyi bir çözüm. C++ dışındaki ana diller arasında Java bu tür dönüşüm operatörlerini desteklemiyor. C# ise destekliyor.

Dönüşüm operatörü en çok sınıfın içindeki bir alan dışarıya açmak veya bir hesaplama yapmak için kullanılır.

1. Dönüşüm operatörünün kopya dönen metod imzası aşağıdaki gibidir.
operator T() const // const olmak zorunda değil!
2. Referans dönen metod imzası ile şöyle.
operator T&();
operator const T&() const;
3. explicit metod imzası şöyle
explicit operator int() const;
Bu durumda static_cast ile şöyle yaparız.
Foo foo;
int i = static_cast<int>(foo);
explicit yazısında da explicit metod konusu mevcut.

Dönüşüm operatörü ne zaman çağırılır?
Cevabı buradan aldım.

1. Bir değişken başka bir tipe cast edilince

Çağırmak için static_cast<> veya C tarzı cast yapmak gerekir.

2. Ya da nesnemizi bir metoda parametre olarak geçerse, dönüşüm öperatörü derleyici tarafından otomatik çağırılır.

3. Değişken başka tipten bir başka değişkene atanınca.

4. Değişkenimiz bir başka tip için copy-construct veya ilklendirme (initialize) amacıyla kullanılınca.

Dönüşüm operatörü ne için kullanılmalı?
Bence mümkünse dönüşüm operatörü yerine getter() metodlar kullanılmalı. Ancak eğer illaki kullanılacaksa sınıfı sadece primitive bir tipe dönüştürmek için kullanılmalı. Mesela sınıfı bool tipine çevirmek için kullanılabilir.

Bazı örnekler
Aşağıda gördüğüm bazı dönüşüm örnekleri var.

double operatörü
Şöyle yaparız:
struct MoreDouble
{
   operator double() { return 42.5; }
};
int operatörü
Şöyle yaparız.
class Foo {
public:
    operator int() const;
    ...
};
Şöyle kullanırız.
Foo foo;
int i = foo;

FILE* operatörü
Örnek:
class File_ptr{
    FILE* p;
public:
    File_ptr(const char* n, const char* a){p = fopen(n, a);}
    File_ptr(FILE* pp) { p = pp; }
    ~File_ptr() {fclose(p);}
    operator FILE* () {return p;} 
};

C++11 ile dönüşüm operatörünün rvalue ile kullanılmamasını sağlamak için aşağıdaki gibi yapılabilir.
operator FILE* () & { return p; }
// Note this -----^

Template Şeklinde Operator
Örnekte degree ve radyan isminde iki sınıf tanımlanmış. static_cast ile bir sınıftan diğerine olan dönüşüm operatörü çağırılıyor.
int main()
{
    using degs = degrees<float>;
    using rads = radians<float>;

    auto d = degs{10};
    auto r = static_cast<rads>(d);

    std::cout << d << std::endl;
    std::cout << r << std::endl;

    return 0;
}

Virtual metod gibi çalışma örneği
Dönüşüm operatörleri aslında dönüşüm fonksiyonları şeklinde isimlendirilselerdi daha iyi olurdu. Çünkü operatörden çok virtual metodlar gibi çalışıyorlar. Örnekte nesnenin dinamik tipi yani B'nin dönüşüm operatörü kullanılıyor.
class B;

struct A {
    virtual operator B() const = 0;
};

struct B : A
{
    public:
        operator B() const{ return B(); } // virtual override

    private:
        int m_i;
};

A const & q = B(); // q has dynamic type B, static type A
B r = q; // Convert A to B using B::operator B()



1 yorum:

  1. Çok güzel bir türkçe kaynak serisi olmuş. Elinize sağlık.

    YanıtlaSil