C++11'in Bazı Yenilikleri ve D'deki Karşılıkları



Benzer belgeler
C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak: Published by Juan Soulié

NESNEYE YÖNELİK PROGRAMLAMA

1 PROGRAMLAMAYA GİRİŞ

NESNEYE YÖNELİK PROGRAMLAMA

Lambda İfadeleri (Lambda Expressions)

C++ Dersi: Nesne Tabanlı Programlama 2. Baskı

BĠLGĠSAYAR PROGRAMLAMA II C++ Programlamaya GiriĢ Published by Juan Soulié

C++ Dersi: Nesne Tabanlı Programlama

C++0x - Sağ Taraf Değerine Bağlanan Referanslar (Rvalue References)

C++ Dersi: Nesne Tabanlı Programlama

NESNEYE YÖNELİK PROGRAMLAMA C++ a Giriş

YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ. 3. Hafta

C++ Operatörler (Operators)

C++ Dersi: Nesne Tabanlı Programlama

HSancak Nesne Tabanlı Programlama I Ders Notları

C++ Dersi: Nesne Tabanlı Programlama

Standard Template Library

Ders 8: Metotlar. barisgokce.com

D Programlama Dili Ali Çehreli

Operatörlere Yeni İşlevler Yüklenmesi (Operator Overloading)

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) {

BTEP243 Ders 3. class Yazım Kuralı:

C++ Dersi: Nesne Tabanlı Programlama

C de Detaylı Üs Alma Programı. C# Dilinde Metot Tanımlama ve Yazdırma

11- FONKSİYONLAR (FUNCTIONS)

DİZİLER-KATARLAR ALGORİTMA VE PROGRAMLAMA II

Dizi nin Önemi. Telefon rehberindeki numaralar, haftanın günleri gibi v.b.

Operator Aşırı Yükleme (Operator OverLoading)

TEMPLATES. Binnur Kurt Bilgisayar Mühendisliği Bölümü İstanbul Teknik Üniversitesi. C++ ile Nesneye Dayalı Programlama 1

Programlama Dilleri. C Dili. Programlama Dilleri-ders08/ 1

Göstericiler (Pointers)

Sınıflar ve Yapılar Arasındaki Farklılıklar. Değer ve Referans Türde Olan Aktarımlar

C++ Dersi: Nesne Tabanlı Programlama

Sınav tarihi : Süre : 60 dak. a) ABCDE b) BCDE c) ABCD d) kod hatalı e) BCD

Veri Yapıları. Amaçlar: Temel Veri Yapılarını Tanımlamalı Veri Yapılarını Veri Modeli ve Türlerini Öğreneceksiniz. İçindekiler:

C# Programlama Dili. İlk programımız Tür dönüşümü Yorum ekleme Operatörler

NESNEYE YÖNELİK PROGRAMLAMA

Bölüm 9. Altprogramlar ISBN

MAK 1005 Bilgisayar Programlamaya Giriş. Fonksiyonlar. Prof. Dr. Necmettin Kaya

Statik veri üyeleri sınıf dosyası içerisinde, ancak sınıf bildirimi dışında başlatılmalıdır. Statik üye fonksiyonları

Programlama Dilleri 1. Ders 12: Belirleyiciler ve Niteleyiciler

ALGORİTMA VE PROGRAMLAMA II

NESNEYE YÖNELİK PROGRAMLAMA SINIFLAR

Nesneye Dayalı Programlama Laboratuvarı

Yrd. Doç. Dr. Caner ÖZCAN

/ C Bilgisayar Programlama Final Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

Görsel Programlama 1

BMT 101 Algoritma ve Programlama I 5. Hafta. Yük. Müh. Köksal Gündoğdu 1

Programlama Dilleri 3

C++ Hata Düzeneği Güvenliği

KAYITLAR BÖLÜM Giriş

10/17/2007 Nesneye Yonelik Programlama 3.1

Pointers (İşaretçiler)

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0

ANA SINIF TÜRETİLEN BİRİNCİ SINIF TÜRETİLEN İKİNCİ SINIF

Yrd. Doç. Dr. Caner ÖZCAN

Nesne Yönelimli Programlama

Nesne Tabanlı Programlama

Sınav tarihi : Süre : 60 dak.

NESNE TABANLI PROGRAMLAMA-1 DERS UYGULAMALARI (22 EYLÜL - 14 KASIM

işlemler bittikten sonra dosyaların kapatılması uygun olacaktır. Bunun için, fclose(fin);

Nesneye Yönelmek. veya sadece formülleri bilgisayarın anlayacağı dile çevirmeyi bilen birinin C++ kullanma yöntemleri. Gökhan Ünel

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Programlama Dilleri III 1

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler

abstract Sınıflar 1 Sınıf sınıf1 new class Ama aşağıdaki şekilde referans alınabilir;

Öğr. Gör. Serkan AKSU 1

C# Yazım Kuralları ERCİYES. Ü. BİLGİSAYAR M. COMPUTER PROGRAMMING II 1 FEHİM KÖYLÜ

BİLG Dr. Mustafa T. Babagil 1

Diziler. Yrd.Doç.Dr.Bülent ÇOBANOĞLU

BİLGİSAYAR MÜHENDİSLİĞİ ALGORİTMA VE PROGRAMLAMA II 2.HAFTA SWİTCH (CASE), SAYAÇLAR, DÖNGÜLER,

Sunum İçeriği. Programlamaya Giriş

Sınav tarihi : Süre : 60 dak. c) En başta #include<stdio.h> yazılmamıştır. c) zt d) Pi e) X0

Nesne Tabanlı Programlama

Karma C/C + + Kodlama

PROGRAMLAMAYA GİRİŞ DERS 2

Temel Bilgisayar Bilimleri Ders Notu #4-2. kısım

ALGORİTMA VE PROGRAMLAMA II

2 PYTHON A GIRIŞ 13 PyCharm İle Python Projesi Oluşturma 15 Projenin Çalıştırılması 18 İlk Python Programımız 19 Açıklama Satırları 21

String ve Karakter Dizileri. Yrd. Doç. Dr. Fehim KÖYLÜ Erciyes Üniversitesi Bilgisayar Mühendisliği Bölümü

C Programlama Dilinde Değişkenler

Örnek1: #include <iostream> #include <string> using namespace std;

Değişkenler, içerisinde tek bir değer tutabilen yapılardır. Örneğin haftanın günlerini değişkenlerde tutmak istersek, her bir gün adı için bir

Değişkenler. Geçerli değişken isimleri : baslamazamani, ad_soyad, x5 Geçersiz değişken isimleri : 3x, while

NESNEYE YÖNELİK PROGRAMLAMA THIS İŞARETÇİSİ, KOPYA YAPICI FONKSİYON, STATİK ELEMANLAR, ARKADAŞ SINIF VE FONKSİYONLAR,NESNE DİZİLERİ

sayi=3 harf=a reelsayi=8.72 Bellek durumu 5. İşaretç iler (pointers)

Programlama Dilleri 1. Ders 4: Diziler

Aynı tipten çok sayıda değişken topluluğudur. X Y Score1 Score2 (0) (1) (2)...

C++ Dersi: Nesne Tabanlı Programlama

C#(Sharp) Programlama Dili

Görsel Programlama DERS 03. Görsel Programlama - Ders03/ 1

Algoritma ve Programlama: Karar Yapıları ve Döngüler

BLM 111 ALGORİTMA VE PROGRAMLAMA I

BİL-142 Bilgisayar Programlama II

/ C Bilgisayar Programlama Yıliçi Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

Bölüm 11. Soyut veri tipleri ve kapsülleme kavramları ISBN

enum bolumler{elektronik, insaat, bilgisayar, makine, gida};

Örnek: İki fonksiyondan oluşan bir program. Fonksiyon Tanımı

ALGORİTMA VE PROGRAMLAMA I

B02.6 Karar Verme, Eşitlik ve Bağıntı Operatörleri

Transkript:

C++11'in Bazı Yenilikleri ve D'deki Karşılıkları Ali Çehreli 30 Haziran 2012; Tütev, Ankara http://ddili.org 1

C++11 Kısaltmalar: İlk standart: C++98 2003'teki technical report'un eklenmiş hali: C++03 2011'deki standart: C++11 Denemek için: Yeni bir Visual C++ g++ 4.7.0 veya daha yenisi, -std=c++0x seçeneği ile: g++ -std=c++0x deneme.cpp vs. http://ddili.org 2

Otomatik Tür Çıkarsama Eski Yetersizlik Türlerin açık açık yazılmasının gereksiz olduğu durumlar: isim_alanim::sinif * p = new isim_alanim::sinif(); for (std::list<int>::const_iterator it = l.begin(); it!= l.end(); ++it) sizeof bir ifadenin türünün büyüklüğünü verir. Onun bir adım öncesi olan ve bir ifadenin türünü veren typeof standart değildi: typeof(bir_ifade) a; // standart degildi http://ddili.org 3

Otomatik Tür Çıkarsama Eski Çözüm Tür isimlerini typedef ile kısaltmak (bu aslında başka zamanlarda da yararlıdır): typedef std::list<int> Sayilar; typedef Sayilar::const_iterator SayilarIt; for (SayilarIt it = l.begin(); it!= l.end(); ++it) Derleyicilerin ek olanaklarından yararlanmak: typeof (bir_ifade) a; http://ddili.org 4

Otomatik Tür Çıkarsama Yeni Çözüm Bütünüyle etkisizleşmiş olan auto anahtar sözcüğü C++11 ile yeni bir hayat buldu ve türünü otomatik olarak çıkarsa anlamını kazandı: auto * p = new isim_alanim::sinif(); for (auto it = l.begin(); it!= l.end(); ++it) typeof değil ama decltype geldi: decltype(bir_ifade) a; http://ddili.org 5

Otomatik Tür Çıkarsama D'deki Karşılığı auto C'deki anlamını yeniden kazanmıştır: otomatik yaşam süreçli değişken. Otomatik tür çıkarsama için özel bir anahtar sözcük yoktur. import std.stdio; auto foo(t)(t t) T[] sonuç; return sonuç; auto bar() struct S /*... */ return S(); void main() auto a = 42; immutable i = 2.75; const c = foo(0x1_0000_0000); shared s = "merhaba"; auto b = bar(); // vs. // otomatik yaşam süreçli bir int // değişmez bir double // long dilimine referans // paylaşılabilen bir string /* Voldemort türü; ismi söylenemez! * (aslında deneme.bar.s) */ immutable tablo = [ "abc" : 1.5, "çde" : 5.25 ]; // double[string] foreach (anahtar, değer; tablo) // anahtar: string, değer: double http://ddili.org 6

Aralıklar için for Döngüsü Eski Yetersizlik Amaç bütün elemanlar için demek olduğunda for döngüsü gereksiz tekrar içerir: for (auto it = l.begin(); it!= l.end(); ++it) Farklı topluluklar için farklı yazılması gerekebilir. Örneğin, dizilerde indeksleri arttırarak ve [] işleciyle: int dizi[5] = 1, 2, 3, 4, 5 ; for (size_t i = 0; i!= 5; ++i) ++dizi[i]; http://ddili.org 7

std::for_each algoritması: Serbest işlevle: Aralıklar için for Döngüsü void karesini_goster(int sayi) cout << sayi * sayi << '\n'; Eski Çözüm for_each(v.begin(), v.end(), karesini_goster); operator() işleciyle: template <class T> struct KareGosterici void operator() (T sayi) const cout << sayi * sayi << '\n'; ; KareGosterici<int> gosterici; for_each(v.begin(), v.end(), gosterici); http://ddili.org 8

Aralıklar için for Döngüsü Yeni Çözüm Diziler dahil, bütün toplulukların bütün elemanları üzerinde ilerlemek için aralık for'u (range for): for (auto eleman : v) karesini_goster(eleman); int dizi[5] = 1, 2, 3, 4, 5 ; for (int & sayi : dizi) ++sayi; http://ddili.org 9

Aralıklar için for Döngüsü Yeni Çözüm (devam) begin() ve end() işlevini tanımlamış olan kullanıcı türleriyle de uyumludur. Bu işlevlerin o aralığa uygun bir erişici (iterator) döndürmeleri gerekir: #include <iostream> struct Ikiserli int bas_, son_; Ikiserli(int bas, int son) : bas_bas, son_son struct const_iterator int deger_; explicit const_iterator(int deger) : deger_deger ; bool operator!= (const const_iterator that) const return deger_!= that.deger_; void operator++ () deger_ += 2; int operator* () return deger_; ; const_iterator begin() const return const_iterator(bas_); const_iterator end() const return const_iterator(son_); int main() Ikiserli aralik10, 20; for (auto sayi : aralik) std::cout << sayi << '\n'; http://ddili.org 10

Aralıklar için for Döngüsü D'deki Karşılığı foreach döngüsü diziler, dilimler, eşleme tabloları, ve kullanıcı türleri ile uyumludur: auto dizi = [ 1, 3, 5, 7 ]; foreach (sayı; dizi) auto tablo = [ "abc" : 1.5, "çde" : 5.25 ]; // double[string] foreach (anahtar, değer; tablo) http://ddili.org 11

Aralıklar için for Döngüsü Kullanıcı türleri için iki yöntem vardır: D'deki Karşılığı (devam) Çoğu durum için en basit olarak InputRange işlevleri: import std.stdio; struct İkişerli int baş, son; bool empty() const @property return baş >= son; int front() const @property return baş; void popfront() baş += 2; void main() auto aralık = İkişerli(10, 20); foreach (sayı; aralık) writeln(sayı); opapply() işlevi: class Okul Öğrenci[] öğrenciler; Öğretmen[] öğretmenler; int opapply(int delegate(ref Öğrenci) işlemler) /*... */ int opapply(int delegate(ref Öğretmen) işlemler) /*... */ foreach (Öğrenci öğrenci; okul) /*... */ foreach (Öğretmen öğretmen; okul) /*... */ http://ddili.org 12

İlkleme Listeleri Eski Yetersizlik Dizilere ayrıcalık: const int d[] = 1, 7, 42 ; // derlenir const vector<int> v = 1, 7, 42 ; // C++03 derleme hatasi http://ddili.org 13

İlkleme Listeleri Eski Çözüm 1. Diziden ilklemek: const int d[] = 1, 7, 42 ; const vector<int> v0(d, d + ELEMAN_ADEDI(d)); // veya: const vector<int> v1(dizi_basi(d), DIZI_SONU(d)); 2. İşlevden döndürmek: vector<int> kur() vector<int> v; v.push_back(1); v.push_back(7); v.push_back(42); return v; const vector<int> v = kur(); 3. boost::assign::list_of'un ilginç ve hoş söz dizimi ile: 4. vs. #include <boost/assign.hpp> using namespace boost::assign; const vector<int> v = list_of(1)(7)(42); http://ddili.org 14

İlkleme Listeleri Yeni Çözüm karakterleri ile gruplamak initializer_list parametresi olarak belirir: class Dizi std::vector<int> v_; public: Dizi(const std::initializer_list<int> & degerler) : v_degerler ; Dizi d0 = 1, 7, 42 ; Dizi d1( 1, 7, 42 ); Dizi d2 1, 7, 42 ; İşlevlerle de kullanılabilir: void foo(const std::initializer_list<double> & parametreler) foo( 1.5, 2.5 ); // karakterleri ilkleme anlaminda oldugu icin // islev cagirirken yasal degil: foo 1.5, 2.5 ; // derleme HATASI http://ddili.org 15

İlkleme Listeleri Yeni Çözüm (devam) initializer_list'in elemanlarına aralık for'u ile de erişilebilir: class Dizi public: Dizi(const std::initializer_list<int> & degerler) for (auto deger : degerler) // deger'i kullan ; Dizi d0 = 1, 7, 42 ; Dizi d1( 1, 7, 42 ); Dizi d2 1, 7, 42 ; http://ddili.org 16

İlkleme Listeleri D'deki Karşılığı Belirsiz sayıda parametreli işlevler (variadic functions): class Dizi int[] değerler; this(int[] değerler...) this.değerler = değerler; auto d0 = new Dizi([ 1, 7, 42 ]); auto d1 = new Dizi(1, 7, 42); auto d2 = new Dizi(1); // Diziyle // Ayrık parametrelerle // Tek parametreyle foreach ile de kullanılabilir: class Dizi this(int[] değerler...) foreach (değer; değerler) // değer'i kullan http://ddili.org 17

İsimsiz İşlevler (lambda functions) Eski Yetersizlik Küçük işlemler için başlı başına işlev tanımlamak bazen fazlaca külfetli olur. Korkunç söz dizimleri: set<ii>::iterator it = find_if(tes.begin(),tes.end(),bind2nd(comp(),ha)); VBI iter = find_if(vb.begin(), vb.end(), boost::bind(&binding::value, _1) == 12); return boost::bind(&bolmeislemi::hesapla, dorde_bolucu, _1); http://ddili.org 18

İsimsiz İşlevler (lambda functions) Eski Çözüm Kodun okunaklılığını arttırmak için yazılan ve belki de tek kere kullanılacak olan işlev nesneleri: #include <algorithm> #include <vector> #include <iostream> using namespace std; struct tam_kati int bolen_; tam_kati(int bolen) : bolen_bolen ; bool operator() (int sayi) return (sayi % bolen_) == 0; int main() vector<int> v 1, 10, 22, 30 ; auto it = find_if(v.begin(), v.end(), tam_kati(11)); if (it!= v.end()) cout << *it << '\n'; http://ddili.org 19

İsimsiz İşlevler (lambda functions) Yeni Çözüm İsimsiz işlevler hazır değer (literal) olarak kod içinde tanımlanabilirler: auto it = find_if(v.begin(), v.end(), [] (int sayi) return (sayi % 11) == 0; ); Değişkenlere atanabilirler: Söz dizimi: auto kistas = [] (int sayi) return (sayi % 11) == 0; ; auto it = find_if(v.begin(), v.end(), kistas); [] parantezleri (capture specification) kapsamdaki değişkenleri yakalamak içindir: int bolen = 0; cin >> bolen; auto kistas = [&] (int sayi) return (sayi % bolen) == 0; ; Dönüş türü otomatiktir. Belirtmek gerektiğinde işlev parantezlerinden sonra yazılır: auto a = [] (int a) -> int return a + 7; ; cout << a(42); http://ddili.org 20

İsimsiz İşlevler (lambda functions) Yeni Çözüm (devam) [] Hiçbir değişkeni yakalama [&] Kullanılan bütün değişkenleri referans olarak yakala [=] Kullanılan bütün değişkenleri kopya olarak yakala [=, &a] a'yı referans olarak yakala; diğerlerini kopyala [b] Yalnızca b'yi kopyala [this] Bu sınıfın this göstergesini kopyala (bütün üyelerin erişimini açar) Uyarı: Referans olarak alınan değişkenler kapsamdan çıkıldığında geçersizdir: std::function<void (void)> f; // "void döndüren void alan işlev" anlamında f = [&] () cout << "Merhaba"; ; f(); int b = 7; // yerel değişken f = [&] () b = 42; ; // HATA: Geçersiz olan b'ye erişir. http://ddili.org 21

İsimsiz İşlevler (lambda functions) D'deki Karşılığı C'deki işlev göstergelerinin eşdeğeri olan function ve kapsamdaki değişkenlere erişim sağlayabilen delegate: import std.array; import std.stdio; import std.algorithm; void main() int[] dizi = [ 1, 10, 22, 30 ]; auto sonuç = find!((sayı) return (sayı % 11) == 0; )(dizi); if (!sonuç.empty) writeln(sonuç.front); Daha kısa olarak: auto sonuç = find!(sayı => (sayı % 11) == 0)(dizi); http://ddili.org 22

İsimsiz İşlevler (lambda functions) D'deki Karşılığı (devam) Çöp toplayıcı yerel değişkenleri gerektiği kadar canlı tutar: import std.stdio; import std.string; alias int delegate() Temsilci; Temsilci temsilciyap(int i) int arahesap = i * 5; string dizgi = format("%s", i); Temsilci temsilci = () return dizgi.length + arahesap; ; return temsilci; /* Yukarıdaki son iki satırın eşdeğeri: * * return () => dizgi.length + arahesap; */ void main() auto temsilci = temsilciyap(10); auto sonuç = temsilci(); writeln(sonuç); Döndürülen temsilcinin yerel arahesap ve dizgi değişkenlerini kullanıyor olması hata değildir; yerel kapsam temsilci yaşadığı sürece geçerlidir. http://ddili.org 23

Sabit İfadeler Eski Yetersizlik C++'ta sabit ifadeler aritmetik işlemler gibi çok basit ifadelerle kısıtlıdır: int dizi[7 * 24] = ; Derleyici tanımlarını görebiliyor olsa bile sabit değer döndüren işlevler kullanılamazlar: int haftadagun() return 7; int gundesaat() return 24; int dizi[haftadagun() * gundesaat()] = ; // derleme HATASI http://ddili.org 24

Sabit İfadeler Yeni Çözüm Programcı ifadenin sabit olduğunu constexpr anahtar sözcüğü ile garanti edebilir: constexpr int haftadagun() return 7; constexpr int gundesaat() return 24; int dizi[haftadagun() * gundesaat()] = ; // derlenir http://ddili.org 25

Sabit İfadeler D'deki Karşılığı D'nin CTFE (Compile Time Function Execution) olanağı son derece güçlüdür: Derleme zamanında işletilebilen her işlev sabit değerler için kullanılabilir: string menü(string başlık, string[] seçenekler, int genişlik) string sonuç = ortalanmışsatır("-= " ~ başlık ~ " =-", genişlik); foreach (seçenek; seçenekler) sonuç ~= ortalanmışsatır(". " ~ seçenek ~ ".", genişlik); return sonuç; string ortalanmışsatır(string yazı, int genişlik) string girinti; if (yazı.length < genişlik) foreach (i; 0.. (genişlik - yazı.length) / 2) girinti ~= ' '; return girinti ~ yazı ~ '\n'; void main() enum tatlımenüsü = menü("tatlılar", [ "Baklava", "Kadayıf", "Muhallebi" ], 30); string beklenendeğer = " -= Tatlılar =-\n" ". Baklava.\n" ". Kadayıf.\n" ". Muhallebi.\n"; assert(tatlımenüsü == beklenendeğer); http://ddili.org 26

rvalue Referansları Eski Yetersizlik İsimleri atama işlecinin solunda ve sağında yer alabilmelerinde gelir: lvalue (sol değer): Genellikle, adresi alınabilen değişkenlerdir (örneğin, isimli değişkenler). rvalue (sağ değer): Genellikle, adresi alınamayan değişkenlerdir (çoğunlukla isimsiz, geçici değişkenler). C++'ta kopyalama (by-copy) temeldir: vector<int> sayilariolustur() vector<int> sayilar; return sayilar; vector<int> s = sayilariolustur(); // (Evet, RVO ve NRVO eniyileştirmeleri uygulanabilir; gözardı ediyorum.) Oysa, döndürülen nesnenin içeriği hedefe aktarılabilse (move) büyük hız kazancı sağlanabilir. http://ddili.org 27

rvalue Referansları Eski Yetersizlik (devam) Geçici nesne vector'ün ara belleğine kopyalanmak zorundadır: vector<yapi> v; v.push_back(yapi(42, "abc")); Oysa, bir daha hiçbir biçimde kullanılamayacak olan geçici nesnenin içeriği vector'ün ara belleğindeki elemana aktarılabilse büyük hız kazancı sağlanabilir. http://ddili.org 28

rvalue Referansları Yeni Çözüm C++11, rvalue referanslarını belirlemek için T&& söz dizimini getiriyor: struct Yapi vector<int> v_; Yapi(const vector<int> & v) : v_v Yapi(vector<int> && v) : v_std::move(v) Yapi(const Yapi & diger) : v_diger.v_ // lvalue ile kurma // rvalue ile kurma // lvalue'dan kopya Yapi(Yapi && diger) // rvalue'dan aktarma : v_std::move(diger.v_) ; // Dikkat: v_diger.v_ kopyalar; aktarmaz! vector<int> vectoryap() vector<int> v; return v; Yapi YapiYap() return Yapi(/*... */); int main() vector<int> v 1, 2, 3 ; Yapi y0v; Yapi y1vectoryap(); Yapi y2y0; Yapi y3yapiyap(); // v'yi kopyalayarak kurar // döndürülen vector'ü aktararak kurar // y0'ı kopyalayarak kurar // döndürülen nesneyi aktararak kurar http://ddili.org 29

rvalue Referansları D'deki Karşılığı D bu sorunu tasarım aşamasında çözmüştür: Sınıflar referans türü olduklarından sınıflarda zaten böyle bir sorun yoktur. Yapılar bellekte serbestçe kaydırılabilen türlerdir. (D, kendi içine referans bulunduran yapıları yasaklar.) Bu sayede aktarma (move) derleyici tarafından zaten uygulanır. Yapı nesneleri ancak gerçekten gereken durumlarda kopyalanırlar. O zaman kullanıcının tanımlamış olduğu kopya sonrası (post-blit (BLock Transfer)) işlevi çağrılır. http://ddili.org 30

rvalue Referansları D'deki Karşılığı (devam) Örnek: struct Yapı int[] dizi; this(const ref int[] dizi) this.dizi = dizi.dup; // lvalue ile kurma this(int[] dizi) // rvalue ile kurma this.dizi = dizi; // <-- ucuz çünkü dilimler referans türleridir this(this) dizi = dizi.dup; // kopya sonrası (post-blit (BLock Transfer)) int[] diziyap() int[] dizi; return dizi; Yapı YapıYap() return Yapı(/*... */); void main() int[] dizi = [ 1, 2, 3 ]; auto y0 = Yapı(dizi); auto y1 = Yapı(diziYap()); auto y2 = y0; auto y3 = YapıYap(); // dizi'yi kopyalayarak kurar // döndürülen vector'ü aktararak kurar // y0'ı kopyalayarak kurar // döndürülen nesneyi aktararak kurar http://ddili.org 31