Pertanyaan Mewajibkan fungsi virtual menimpa untuk menggunakan kata kunci pengganti


C ++ 11 ditambahkan override untuk memastikan bahwa fungsi anggota yang Anda tulis yang Anda maksudkan untuk menggantikan fungsi virtual kelas dasar benar-benar dilakukan (atau tidak akan dikompilasi).

Namun dalam hierarki objek besar, terkadang Anda dapat secara tidak sengaja menulis fungsi anggota yang menimpa virtual kelas dasar saat Anda tidak menginginkannya! Contohnya:

struct A {
    virtual void foo() { }  // because obviously every class has foo().
};

struct B : A { ... };

class C : B {
private:
    void foo() {
        // was intended to be a private function local to C
        // not intended to override A::foo(), but now does
    }
};

Apakah ada beberapa flag / ekstensi penyusun yang setidaknya akan mengeluarkan peringatan C::foo ? Agar mudah dibaca dan benar, saya hanya ingin menerapkan bahwa semua menimpa penggunaan override.


32
2018-03-19 13:10


asal


Jawaban:


Sepertinya rilis 5.1 GCC ditambahkan persis PERINGATAN Aku sedang mencari:

-Wsuggest-override
  Peringatkan tentang fungsi virtual yang menggantikan yang tidak ditandai dengan kata kunci penggantian.

Kompilasi dengan -Wsuggest-override  -Werror=suggest-override kemudian akan menegakkan bahwa semua menimpa penggunaan override.


25
2018-04-26 14:38



Ada dua hal yang bisa Anda lakukan.

Pertama, Clang 3.5 dan lebih tinggi memiliki -Winconsistent-missing-override peringatan (dipicu oleh -Wall). Ini tidak cukup berhasil untuk contoh Anda, tetapi hanya jika Anda akan menambahkan void foo() override {} untuk class B dan tidak dalam class C. Apa yang sebenarnya Anda inginkan adalah -Wmissing-override, untuk menemukan semua yang hilang override, bukan hanya yang hilang secara tidak konsisten. Yang saat ini tidak disediakan, tetapi Anda mungkin mengeluh pada milis Clang dan mereka mungkin menambahkannya.

Kedua, Anda gunakan Trik Howard Hinnant untuk untuk sementara menambahkan final ke fungsi anggota kelas dasar dan mengkompilasi ulang. Compiler kemudian akan mencari semua kelas turunan selanjutnya yang mencoba untuk mengesampingkan virtual fungsi anggota basis. Anda kemudian dapat memperbaiki yang hilang. Ini adalah pekerjaan yang lebih sedikit dan membutuhkan pengecekan ulang secara rutin ketika hirarki kelas Anda meluas.


10
2018-03-19 20:15



Masalah yang saya lihat -Werror=suggest-override adalah bahwa itu tidak memungkinkan Anda untuk menulis yang berikut:

void f() final {...}

Meskipun ada yang tersirat override sini. Itu -Werror=suggest-override tidak mengabaikan ini (seperti seharusnya, karena override redundan dalam hal ini)

Tapi itu lebih rumit dari itu ... Jika Anda menulis

virtual void f() final {...}

Itu berarti hal yang sama sekali berbeda

virtual void f() override final {...}

Kasus pertama tidak perlu menimpa apapun! Yang kedua tidak.

Jadi saya berasumsi bahwa pemeriksaan GCC diterapkan dengan cara ini (yaitu terkadang menerima redundan override) untuk mendapatkan kasus terakhir yang benar. Tapi ini tidak bermain dengan baik misalnya. dengan clang-tidy, yang akan dengan benar menghapus override ketika final sudah cukup (tetapi kemudian kompilasi GCC akan gagal ...)


2
2018-03-23 17:24



GCC dan Clang ditutupi oleh jawaban lain. Ini sama untuk VC ++ dari jawaban saya yang lain:

Di bawah ini adalah nomor peringatan yang relevan di VC ++:

C4263 (level 4) 'function': member function does not override any base class virtual member function
C4266 (level 4) 'function': no override available for virtual member function from base 'type'; function is hidden

Untuk mengaktifkan dua peringatan ini, Anda dapat menggunakan salah satu opsi berikut:

  1. Setel tingkat peringatan ke 4 dalam pengaturan proyek dan kemudian nonaktifkan peringatan yang tidak Anda inginkan. Ini adalah cara yang saya sukai. Untuk menonaktifkan peringatan Level 4 yang tidak diinginkan, masuk ke pengaturan proyek> C / C ++> Lanjutan lalu masukkan nomor peringatan di kotak Nonaktifkan Peringatan Spesifik.
  2. Aktifkan di atas dua peringatan menggunakan kode.

    #pragma warning(default:4263)
    #pragma warning(default:4266)
    
  3. Aktifkan di atas dua peringatan dalam pengaturan proyek> C / C ++> Command Line dan kemudian masukkan / w34263 / w34266. Opsi di sini / wNxxxx berarti mengaktifkan peringatan xxxx di Level N (N = 3 adalah level default). Anda juga dapat melakukan / wdNxxxx yang menonaktifkan peringatan xxxx di level N.


-1
2017-12-12 21:29