Destructor virtual murni dalam C ++

163

Apakah salah menulis:

class A {
public:
    virtual ~A() = 0;
};

untuk kelas dasar abstrak?

Setidaknya itu mengkompilasi di MSVC ... Apakah akan crash pada saat dijalankan?

Ivan Krechetov
sumber
9
Mungkin dikompilasi, tetapi apakah tautannya?
Mooing Duck

Jawaban:

218

Iya. Anda juga perlu mengimplementasikan destructor:

class A {
public:
    virtual ~A() = 0;
};

inline A::~A() { }

harus cukup.

Dan karena ini mendapat suara turun, saya harus mengklarifikasi: Jika Anda memperoleh sesuatu dari A dan kemudian mencoba untuk menghapus atau menghancurkannya, Adestructor akhirnya akan dipanggil. Karena murni dan tidak memiliki implementasi, perilaku yang tidak terdefinisi akan terjadi. Pada satu platform populer, itu akan memanggil purecall handler dan crash.

Sunting: memperbaiki deklarasi agar lebih selaras, dikompilasi dengan http://www.comeaucomputing.com/tryitout/

MSN
sumber
16
Um, ya itu. Murni hanya berarti kelas turunan juga perlu menyediakan implementasi.
MSN
72
Menerapkan fungsi virtual murni sebenarnya legal. Sangat berguna untuk memberikan implementasi standar tetapi memaksa subclass untuk menyebutnya secara eksplisit.
jmucchiello
6
MSN dan perhatikan jika Anda memiliki definisi itu di header, Anda harus meletakkan "inline" di depan untuk menghindari pelanggaran ODR (satu aturan definisi)
Johannes Schaub - litb
2
Mengapa A :: ~ A () harus didefinisikan secara eksplisit, karena, saya pikir ada destruktor default untuk setiap objek? Seperti pada semua jenis warisan, rantai destruktor selalu disebut dan destruktor kelas dasar tidak harus selalu didefinisikan.
jeffD
11
Cara yang lebih baik untuk mengatakannya adalah bahwa begitu Anda mendeklarasikan destruktor, itu tidak secara otomatis diterapkan untuk Anda.
MSN
49

Penghancur pribadi: mereka akan memberi Anda kesalahan ketika Anda membuat objek dari kelas turunan - bukan sebaliknya. Diagnosis mungkin muncul.

12.4 Destructors

6 Destructor dapat dinyatakan virtual (10.3) atau virtual murni (10.4); jika ada objek dari kelas itu atau kelas turunan yang dibuat dalam program, destruktor harus didefinisikan.

Kelas dengan destruktor virtual murni adalah kelas abstrak. Catat dengan baik:

10.4 Kelas abstrak

2 Fungsi virtual murni hanya perlu didefinisikan jika dipanggil dengan, atau seolah-olah dengan (12.4), sintaks kualifikasi-id (5.1).

[ Catatan : deklarasi fungsi tidak bisa memberikan specifier murni dan definisi — catatan akhir]

Diambil langsung dari konsep:

struct C {
   virtual void f() = 0 { }; // ill-formed
};
secara langsung
sumber
14
+1. Saya pikir Herb Sutter juga memiliki beberapa info bagus tentang ini: gotw.ca/gotw/031.htm . Sangat menarik untuk dicatat bahwa fungsi virtual murni mungkin memiliki implementasi yang disediakan, bukan hanya destruktor.
Fred Larson
6
Ya, itu adalah sesuatu yang Anda lakukan dalam sebuah wawancara untuk menakuti pewawancara Anda;)
dirkgently
1
Sebenarnya bukan itu yang biasa, dalam pengalaman saya.
@Neil Butterworth: Yang mana?
dirkgently
@Dirk - skenario "fungsi apa pun". Ini tidak biasa menemukannya terbiasa menerapkan beberapa perilaku umum.