2015-04-23 24 views
14

Aşağıdakilerden birini bildirdiğimde “Beş Kural Kuralı” na göre: kopyalama veya taşıma işlemi ya da yıkıcıyı hepsini yazmalıyım, çünkü derleyici bunları benim için oluşturmuyor (bazıları). Ama eğer sınıfım (A) bir sanal yıkıcıya sahip bir soyut sınıftan geliyorsa, bu, A sınıfındaki yıkıcının "kullanıcı tanımlı" olarak kabul edileceği anlamına mı geliyor? Sonuç olarak, semantiklerin bu sınıfın A nesnesiyle çalışmadığı, çünkü derleyici benim için bir taşıma yapıcısı oluşturmayacak mı? [Class.copy] olarakSoyut sınıflar ve semantik hareketleri

struct Interface { 
    virtual void myFunction() = 0; 
    virtual ~Interface() {}; 
}; 

struct A : public Interface { 
    void myFunction() override {}; 
}; 
+1

Bir soyut sınıf başlatılamaz. –

+0

Hangi derleyiciyi kullanıyorsunuz? – MikeMB

+0

@MikeMB Belirli bir derleyici ile çalışmıyorum. – NiegodziwyBeru

cevap

11

:

bir sınıf X tanımı açıkça bir hareket kurucu bildirebilir etmezse varsayılan olarak, tek örtük ilan edilecek

(ancak ve ancak
9.1) - X, bir kullanıcı tarafından beyan kopya kurucu olmayan,
(9.2) - X, bir kullanıcı tarafından beyan kopya atama operatörü,
(9.3) sahip değildir - X, bir kullanıcı tarafından beyan hareket atama operatör sahip değildir, ve
(9.4) - X, kullanıcı tarafından bildirilen bir yıkıcıya sahip değil.
[Not: hareket yapıcı örtülü beyan veya açıkça aksi yerine kopya kurucu çağırmak olabilir hamle yapıcısı çağrılan olurdu ifadeleri sağlanmayan zaman. -end not]

Interface bir kullanıcısının bildirdiği yıkıcı, bu nedenle Interface 'ın hareket yapıcı örtük varsayılan olarak ilan edilmeyecektir var. Ancak A bu madde işaretlerinden hiçbirine uymuyor - yani varsayılan olarak örtülü bir hareket yapıcıya sahip olacak. A(A&&), nota göre Interface parçasını kopyalayacaktır. Biz Interface ve A ekleyerek üyeleri tarafından doğrulayabilirsiniz:

#include <iostream> 

template <char c> 
struct Obj { 
    Obj() { std::cout << "default ctor" << c << "\n"; } 
    Obj(const Obj&) { std::cout << "copy ctor" << c << "\n"; } 
    Obj(Obj&&) { std::cout << "move ctor" << c << "\n"; } 
}; 

struct Interface { 
    virtual void myFunction() = 0; 
    virtual ~Interface() {}; 

    Obj<'I'> base; 
}; 

struct A : public Interface { 
    void myFunction() override {}; 

    Obj<'A'> derived; 
}; 

int main() { 
    A a1;      // default I, default A 
    std::cout << "---\n"; 
    A a2(std::move(a1));  // copy I, move A 
    std::cout << "---\n"; 
    A a3(a2);     // copy I, copy A 
} 
+1

' Arabirim' varsayılan bir kopya kurucuyu C + 'dan itibaren kullanımdan kaldırılmış bir özellik olarak alır. 11. Yine de son taslaklarda hala var. – dyp

+0

@dyp "Sınıfın kullanıcı tarafından bildirilen bir kopya atama işleci veya kullanıcı tarafından bildirilen bir yok edici varsa, varsa, ikinci durum kullanımdan kaldırılır." Gelecekte hangi revizyon kaldırılacak? C++ 17 belki? – Barry

+3

Bilmiyorum. [N3839] (http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3839.pdf) bunun ne olduğunu bilmediğinden emin değil. - Düzenle: [EWG # 55 oldu] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4327.html#55) Umarım daha fazla uyarı alırız. Yakında (örneğin clang ++ '-Wdeprecated'). – dyp