Apakah kata kunci 'override' hanya berupa pemeriksaan untuk metode virtual yang diganti?

226

Sejauh yang saya mengerti, pengenalan overridekata kunci di C ++ 11 tidak lebih dari sebuah cek untuk memastikan bahwa fungsi yang sedang dilaksanakan adalah fungsi overridedari sebuah virtualkelas dasar.

Itu saja?

aiao
sumber
50
Ya.⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣
R. Martinho Fernandes
13
Ini bukan cek ganda. Ini satu-satunya cek.
Nikos C.
13
hei, menimpa BUKAN kata kunci, itu semacam gula tata bahasa. int override = 42; // Oke
KAlO2
2
Ini juga meningkatkan keterbacaan menjelaskan fungsi yang dideklarasikan ditimpa;)
mots_g
5
Jadi, uh ... Kapan C ++ 11 menjadi standar sehingga mereka mulai mengajarkan hal-hal seperti ini di 4 tahun lokal saya? Kapan mereka akan tahu?
Cinch

Jawaban:

263

Itu memang idenya. Intinya adalah bahwa Anda secara eksplisit tentang apa yang Anda maksudkan, sehingga kesalahan diam dapat didiagnosis:

struct Base
{
    virtual int foo() const;
};

struct Derived : Base
{
    virtual int foo()   // whoops!
    {
       // ...
    }
};

Kode di atas mengkompilasi, tetapi bukan yang Anda maksudkan (catat yang hilang const). Jika Anda mengatakan sebaliknya, virtual int foo() overridemaka Anda akan mendapatkan kesalahan kompiler bahwa fungsi Anda sebenarnya tidak mengesampingkan apa pun.

Kerrek SB
sumber
74
+1: Meskipun, sayangnya, ini adalah herring merah ketika orang-orang menyarankan bahwa overridefitur baru "memperbaiki" ini; Anda harus ingat untuk menggunakannya, sama seperti Anda seharusnya ingat untuk menulis const;)
Lightness Races di Orbit
Saya baru menyadari explicitdefinisi kelas tidak membuatnya menjadi C ++ 11. Hah.
aschepler
1
@aschepler Dan apa yang akan explicitdilakukan definisi kelas? Tidak pernah mendengar tentang itu sama sekali.
Christian Rau
18
@LightnessRacesinOrbit: Ya, itu bukan bukti bodoh; Namun, mengingat aturan umum (penulisan gila overrideketika seseorang bermaksud untuk melakukannya) lebih mungkin daripada mengingat kasus sudut yaitu tidak ada generalitas dalam menyalin fungsi prototipe yang berbeda, hanya penyimpangan seperti hilang constatau menulis charbukan int, dll
legends2k
1
@ Cahaya, kasus penggunaan terbaik dari overridespecifier disebutkan dalam jawaban ini , yang lebih futuristik daripada langsung. Jawabannya menunjukkan bahwa, tetap overridedengan virtualmetode. Di masa depan ketika seseorang keliru mengubah tanda tangan, kegunaannya akan muncul.
iammilind
35

Kutipan Wikipedia:

Override pengidentifikasi khusus berarti bahwa kompiler akan memeriksa kelas dasar untuk melihat apakah ada fungsi virtual dengan tanda tangan yang tepat ini. Dan jika tidak ada, kompiler akan error out.

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

Edit (berupaya sedikit meningkatkan jawabannya):

Mendeklarasikan metode sebagai "override" berarti bahwa metode itu dimaksudkan untuk menulis ulang metode (virtual) pada kelas dasar. Metode utama harus memiliki tanda tangan yang sama (setidaknya untuk parameter input) seperti metode yang ingin ditulis ulang.

Mengapa ini perlu? Nah, dua kasus kesalahan umum berikut ini dicegah:

  1. satu salah ketik tipe dalam metode baru. Compiler, tidak menyadari bahwa ia bermaksud untuk menulis metode sebelumnya, cukup menambahkannya ke kelas sebagai metode baru. Masalahnya adalah bahwa metode lama masih ada, yang baru ditambahkan hanya sebagai kelebihan beban. Dalam hal ini, semua panggilan ke metode lama akan berfungsi seperti sebelumnya, tanpa perubahan perilaku (yang akan menjadi tujuan penulisan ulang).

  2. orang lupa untuk mendeklarasikan metode dalam superclass sebagai "virtual", tetapi masih mencoba untuk menulis ulang dalam subkelas. Meskipun hal ini tampaknya diterima, perilaku tersebut tidak akan persis seperti yang dimaksudkan: metode ini tidak virtual, jadi akses melalui pointer ke superclass akan berakhir memanggil metode lama (superclass ') alih-alih metode baru (subclass').

Menambahkan "override" dengan jelas melemahkan ini: melalui ini, seseorang memberi tahu kompilator bahwa tiga hal mengharapkan:

  1. ada metode dengan nama yang sama di superclass
  2. metode ini di superclass dinyatakan sebagai "virtual" (itu berarti, dimaksudkan untuk ditulis ulang)
  3. metode dalam superclass memiliki tanda tangan (input *) yang sama dengan metode dalam subkelas (metode penulisan ulang)

Jika ada yang salah, maka kesalahan ditandai.

* catatan: parameter output kadang-kadang berbeda, tetapi tipe terkait. Baca tentang transformasi kovarian dan kontravarian jika tertarik.

pengguna1284631
sumber
31

Ditemukan " override " berguna ketika seseorang memperbarui tanda tangan metode virtual kelas dasar seperti menambahkan parameter opsional tetapi lupa memperbarui tanda tangan metode kelas turunan. Dalam hal ini metode antara basis dan kelas turunan tidak lagi berhubungan polimorfik. Tanpa deklarasi override, sulit untuk menemukan bug semacam ini.

pengguna3792211
sumber
1
+1. Meskipun sementara overridemerupakan cara yang bagus untuk menemukan masalah seperti itu, cakupan tes unit yang baik juga harus membantu.
Kecewa
1
Itulah mengapa saya sangat bersemangat tentang specifier baru itu. Satu-satunya masalah adalah bahwa fitur ini harus sudah diterapkan untuk mencegah kesalahan yang disebabkan oleh perubahan kelas dasar. ;-)
Wolf
5

Ya begitulah. Ini adalah cek untuk memastikan seseorang tidak mencoba mengganti dan mengacaukannya melalui tanda tangan yang gagal. Berikut adalah halaman Wiki yang menjelaskan ini secara terperinci dan memiliki contoh ilustrasi pendek:

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

RonaldBarzell
sumber
2

C ++ 17 draft standar

Setelah memeriksa semua overridehits pada draft standar C ++ 17 N4659 , satu-satunya referensi yang dapat saya temukan untuk overridepengidentifikasi adalah:

5 Jika fungsi virtual ditandai dengan override spec-specifier dan tidak mengesampingkan fungsi anggota dari kelas dasar, program ini salah bentuk. [Contoh:

struct B {
  virtual void f(int);
};

struct D : B {
  virtual void f(long) override; // error: wrong signature overriding B::f
  virtual void f(int) override;  // OK
}

- contoh akhir]

jadi saya pikir mungkin meledakkan program yang salah sebenarnya adalah satu-satunya efek.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber