Panduan Gaya C ++ Google. Bagian 2

Bagian 1. Pendahuluan

Bagian 2. File header

...





Saat menulis kode, kita semua menggunakan aturan pemformatan kode. Terkadang aturan ditemukan, dalam kasus lain panduan gaya siap pakai digunakan. Meskipun semua pemrogram C ++ membaca bahasa Inggris lebih mudah daripada yang asli, lebih baik memiliki manual di bahasa Inggris.

Artikel ini adalah terjemahan dari bagian panduan gaya C ++ Google ke dalam bahasa Rusia.

Artikel asli (bercabang di github), terjemahan diperbarui .



File header



Sebaiknya setiap file sumber .cc memiliki file header .h yang cocok . Ada juga pengecualian yang diketahui untuk aturan ini, seperti pengujian unit atau file .cc kecil yang hanya berisi fungsi main () .



Penggunaan file header yang benar dapat berdampak besar pada keterbacaan, ukuran, dan performa kode Anda.



Aturan berikut akan membantu Anda menghindari masalah yang sering terjadi dengan file header.



File header independen



File header harus mandiri (dalam hal kompilasi) dan memiliki ekstensi .h . File lain (non-header) yang dimaksudkan untuk dimasukkan dalam kode harus memiliki ekstensi .inc dan dipasangkan dengan kode penyertaan.



Semua file header harus berdiri sendiri. Pengguna dan alat pengembangan tidak boleh bergantung pada dependensi khusus saat menggunakan file header. File header harus dapat dikunci dan menyertakan semua file yang diperlukan.



Lebih disukai menempatkan definisi untuk template dan fungsi sebaris dalam file yang sama dengan deklarasinya. Dan definisi ini harus disertakan di setiap .ccfile yang menggunakannya, jika tidak, mungkin ada kesalahan tautan pada beberapa konfigurasi build. Jika deklarasi dan definisi berada dalam file yang berbeda, termasuk yang satu harus menyertakan yang lain. Jangan pisahkan definisi ke dalam file header terpisah ( -inl.h ). Sebelumnya, praktik ini sangat populer, sekarang tidak diinginkan.



Sebagai pengecualian, jika semua varian yang tersedia dari argumen template dibuat dari template, atau jika template mengimplementasikan fungsionalitas yang digunakan hanya oleh satu kelas, maka diperbolehkan untuk menentukan template dalam satu (dan hanya satu) file .cc yang menggunakan template ini.



Ada situasi yang jarang terjadi ketika file header tidak mandiri. Ini dapat terjadi jika file disertakan di lokasi non-standar, seperti di tengah file lain. Dalam kasus ini, mungkin tidak ada kunci pengaktifan ulang , dan file header tambahan mungkin juga tidak disertakan. Beri nama file tersebut dengan ekstensi .inc . Gunakan mereka secara berpasangan dan coba sesuaikan persyaratan umum sebanyak mungkin.



Mulai ulang kunci



Semua file header harus #define dilindungi dari penyertaan ulang . Format definisi makro harus: <PROJECT> _ <PATH> _ <FILE> _H_ .



Untuk memastikan keunikan, gunakan komponen jalur file lengkap di pohon proyek. Misalnya, file foo / src / bar / baz.h di proyek foo mungkin memiliki kunci berikut:



#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif  // FOO_BAR_BAZ_H_


Pengumuman awal



Jika memungkinkan, jangan gunakan pengumuman sebelumnya. #Masukkan file header yang diperlukan sebagai gantinya .



Definisi

"Pra-deklarasi" adalah deklarasi kelas, fungsi, template tanpa definisi yang sesuai.



Per



  • . #include ( ) .
  • . #include - .




  • , .
  • API, . , API: , , .
  • std:: .
  • , : #include. , #include ( ) :



          // b.h:
          struct B {};
          struct D : B {};
          // good_user.cc:
          #include "b.h"
          void f(B*);
          void f(void*);
          void test(D* x) { f(x); }  // calls f(B*)
          


    #include B D, test() f(void*).
  • , .
  • Struktur kode yang memungkinkan deklarasi awal (dan, selanjutnya, penggunaan pointer sebagai anggota kelas) dapat membuat kode membingungkan dan lambat.


Putusan



  • Cobalah untuk menghindari pra-deklarasi entitas yang dideklarasikan dalam proyek lain.
  • Saat menggunakan fungsi yang dideklarasikan dalam file header, selalu #include file itu.
  • Saat menggunakan template kelas, sebaiknya #include file header-nya.


Lihat juga aturan untuk penyertaan dalam Nama dan Urutan Sertakan .



Fungsi sebaris



Tentukan fungsi sebagai fungsi sebaris hanya jika ukurannya kecil, misalnya, tidak lebih dari 10 baris.



Definisi



Anda dapat mendeklarasikan fungsi menjadi sebaris dan memberi tahu kompiler untuk menyertakannya secara langsung dalam kode pemanggil, selain cara standar untuk memanggil suatu fungsi.



Kelebihan



Menggunakan fungsi inline dapat menghasilkan kode yang lebih efisien, terutama jika fungsinya kecil. Gunakan fitur ini untuk mendapatkan / mengatur fungsi, singkat dan fungsi penting kinerja lainnya.



Melawan



Penggunaan fungsi inline yang berlebihan dapat membuat program menjadi lebih lambat. Selain itu, fungsi sebaris, bergantung pada ukurannya, dapat menambah atau mengurangi ukuran kode. Jika ini adalah fungsi kecil, maka kodenya dapat diminimalkan. Jika fungsinya besar, maka ukuran kode bisa bertambah banyak. Perhatikan bahwa pada prosesor modern, kode yang lebih ramping berjalan lebih cepat karena penggunaan cache instruksi yang lebih baik.



Putusan



Aturan praktis yang baik adalah tidak membuat fungsi menjadi sebaris jika melebihi 10 baris kode. Hindari membuat perusak sebaris, karena mereka secara implisit dapat berisi banyak kode tambahan: panggilan ke penghancur variabel dan kelas dasar!



Aturan praktis lain yang baik adalah bahwa biasanya tidak masuk akal untuk fungsi inline yang memiliki pernyataan loop atau switch (kecuali dalam kasus yang merosot di mana loop atau pernyataan lain tidak pernah dijalankan).



Penting untuk dipahami bahwa fungsi inline tidak perlu dikompilasi menjadi kode dengan cara ini. Misalnya, biasanya fungsi virtual dan rekursif dikompilasi dengan panggilan standar. Secara umum, fungsi rekursif tidak boleh dideklarasikan sebagai fungsi sebaris. Alasan utama untuk melakukan fungsi virtual sebaris adalah untuk menempatkan definisi (kode) dalam definisi kelas itu sendiri (untuk mendokumentasikan perilaku atau keterbacaan) - sering digunakan untuk fungsi get / set.



Nama dan Cantumkan Pesanan



Sisipkan file header dalam urutan berikut: file berpasangan (misalnya, foo.h - foo.cc), file sistem C, pustaka standar C ++, pustaka lain, file proyek Anda.



Semua header proyek harus relatif terhadap direktori sumber proyek tanpa menggunakan alias UNIX seperti . (direktori saat ini) atau .. (direktori induk). Misalnya, google-awesome-project / src / base / logging.h harus disertakan seperti ini:



#include "base/logging.h"


Contoh lain: jika fungsi utama file dir / foo.cc dan dir / foo_test.cc adalah untuk mengimplementasikan dan menguji kode yang dideklarasikan di dir2 / foo2.h , maka tulis file header dengan urutan berikut:



  1. dir2 / foo2.h .
  2. C (: .h), <unistd.h>, <stdlib.h>.
  3. C++ ( ), <algorithm>, <cstddef>.
  4. .h .
  5. .h .


Pisahkan setiap grup file (tidak kosong) dengan baris kosong.



Urutan file ini memungkinkan Anda untuk mendeteksi kesalahan ketika file header yang diperlukan (sistem, dll.) Hilang dalam file header yang dipasangkan ( dir2 / foo2.h ) dan perakitan file dir / foo.cc atau dir / foo_test.cc yang sesuai akan gagal. Akibatnya, kesalahan akan segera muncul ke pengembang yang bekerja dengan file ini (dan bukan tim lain yang hanya menggunakan pustaka eksternal).



Biasanya file yang dipasangkan dir / foo.cc dan dir2 / foo2.h berada di direktori yang sama (misalnya, base / basictypes_test.cc dan base / basictypes.h ), meskipun ini tidak diperlukan.



Perhatikan bahwa file header C seperti stddef.h biasanya dapat dipertukarkan dengan file C ++ yang sesuai ( cstddef ). Variasi apa pun dapat digunakan, tetapi yang terbaik adalah mengikuti gaya kode yang ada.



Dalam setiap bagian, file header paling baik dicantumkan dalam urutan abjad. Perhatikan bahwa kode yang ditulis sebelumnya mungkin tidak mengikuti aturan ini. Jika memungkinkan (misalnya, saat mengoreksi file), perbaiki urutan file ke yang benar.



Semua file header yang mendeklarasikan tipe yang Anda inginkan harus disertakan, kecuali yang dideklarasikan sebelumnya . Jika kode Anda menggunakan tipe dari bar.h , jangan mengandalkan file lain foo.h untuk menyertakan bar.hdan Anda dapat membatasi diri Anda sendiri dengan hanya menyertakan foo.h : include bar.h secara eksplisit (kecuali dinyatakan secara eksplisit (mungkin dalam dokumentasi) bahwa foo.h juga akan memberi Anda tipe dari bar.h ).



Misalnya, daftar file header di google-awesome-project / src / foo / internal / fooserver.cc mungkin terlihat seperti ini:



#include "foo/server/fooserver.h"
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/server/bar.h"


Pengecualian



Ada kasus ketika Anda perlu memasukkan file header tergantung pada kondisi preprocessor (misalnya, tergantung pada OS yang digunakan). Cobalah untuk membuat penyertaan tersebut sesingkat (dilokalkan) mungkin dan letakkan setelah file header lainnya. Misalnya:



#include "foo/public/fooserver.h"
#include "base/port.h"  // For LANG_CXX11.
#ifdef LANG_CXX11
#include <initializer_list>
#endif  // LANG_CXX11


Catatan:



Gambar diambil dari open source .



All Articles