Sarlavha / cpp faylida sarlavhalar qanday tartibda e'lon qilinishi kerak? Shubhasiz, keyingi sarlavhalar tomonidan talab qilinadiganlar avvalroq bo'lishi kerak va sinfga xos sarlavhalar sarlavha doirasida emas, balki cpp doirasida bo'lishi kerak, lekin belgilangan tartib konventsiyasi/eng yaxshi amaliyot bormi?
C++ sarlavhasi tartibi [yopiq]
Javoblar (10)
Sarlavha faylida uni kompilyatsiya qilish uchun HAMMA sarlavhalarni kiritishingiz kerak. Va ba'zi sarlavhalar o'rniga oldinga siljish deklaratsiyasidan foydalanishni unutmang.
Manba faylida:
- mos keladigan sarlavha fayli
- zarur loyiha sarlavhalari
- Uchinchi tomon kutubxonalari sarlavhalari
- standart kutubxonalar sarlavhalari
- tizim sarlavhalari
Shu tartibda kutubxonalarni o'z ichiga olishni unutgan sarlavha fayllaringizdan hech birini o'tkazib yubormaysiz.
Yaxshi amaliyot: har bir .h faylida .cpp bo'lishi kerak, u .h ni hamma narsadan oldin o'z ichiga oladi. Bu har qanday .h faylini birinchi o'ringa qo'yish mumkinligini isbotlaydi.
Sarlavha amalga oshirishni talab qilmasa ham, siz faqat o'sha .h faylini o'z ichiga olgan .cpp yaratasiz va boshqa hech narsa yo'q.
Bu degani, siz o'zingiz xohlagan tarzda savolingizga javob berishingiz mumkin. Ularni qanday tartibda kiritishingiz muhim emas.
Boshqa ajoyib maslahatlar uchun ushbu kitobni sinab ko'ring: Katta o'lchamli C++ dasturiy ta'minot dizayni - bu juda qimmat bo'lgani achinarli, lekin u C++ manba kodini joylashtirish uchun amalda qo'llanma.
Sarlavha fayllarida men birinchi navbatda standart sarlavhalarni, keyin esa o'z sarlavhalarimni qo'yishga moyilman (har ikkala ro'yxat ham alifbo tartibida tartiblangan). Amalga oshirish fayllarida men birinchi navbatda mos keladigan sarlavhani (agar mavjud bo'lsa), keyin standartlar sarlavhalarini va boshqa bog'liqlik sarlavhalarini qo'ydim.
Buyurtma unchalik ahamiyatga ega emas, agar siz makro va #define
dan katta foydalansangiz; u holda siz belgilagan makros oldingi kiritilgan makro o'rnini bosmasligini tekshirishingiz kerak (albatta, bu siz xohlagan bo'lsa bundan mustasno).
Ushbu bayonot haqida
keyingi sarlavhalar tomonidan talab qilinadiganlar avvalroq bo'lishi kerak
Sarlavha o'zidan oldin kiritilgan boshqa sarlavhalarga tayanmasligi kerak! Agar u sarlavhalarni talab qilsa, u faqat ularni o'z ichiga oladi. Sarlavha himoyachilari bir nechta inklyuziyani oldini oladi:
#ifndef FOO_HEADER_H
#define FOO_HEADER_H
...
#endif
tahrirlash
Men bu javobni yozganimdan so'ng, men kodimga kiritilgan ko'rsatmalarga buyurtma berish usulini o'zgartirdim. Endi men har doim sarlavhalarni standartlashtirishning ortib borayotgan tartibida qo'yishga harakat qilaman, shuning uchun loyihamning sarlavhalari birinchi o'rinda, keyin uchinchi tomon kutubxonalari sarlavhalari, keyin esa standart sarlavhalar.
Misol uchun, agar mening faylimdan biri men yozgan kutubxona, Qt, Boost va standart kutubxonadan foydalansa, men quyidagilarni buyurtma qilaman:
//foo.cpp
#include "foo.hpp"
#include <my_library.hpp>
// other headers related to my_library
#include <QtCore/qalgorithms.h>
// other Qt headers
#include <boost/format.hpp> // Boost is arguably more standard than Qt
// other boost headers
#include <algorithms>
// other standard algorithms
Buni qilishimning sababi o'z sarlavhalaridagi etishmayotgan bog'liqliklarni aniqlashdir: masalan, my_library.hpp
std::copy
dan foydalanadi, lekin <algorithm>
ni o'z ichiga olmaydi, deb faraz qilaylik. Agar foo.cpp
ga <algorithm>
dan keyin qo'shsam, bu etishmayotgan bog'liqlik e'tibordan chetda qoladi. Aksincha, men taqdim etgan buyruq bilan kompilyator std::copy
e'lon qilinmaganidan shikoyat qiladi, bu menga my_library.hpp
ni tuzatishga imkon beradi.
Har bir "kutubxona" guruhida men ularni osonroq topish uchun alifbo tartibida tartiblangan kiritish ko'rsatmalarini saqlashga harakat qilaman.
Yon eslatmada, sarlavha fayllari orasidagi bog'liqlikni maksimal darajada cheklash yaxshi amaliyotdir. Fayllar iloji boricha kamroq sarlavhalarni, ayniqsa sarlavhalar faylini o'z ichiga olishi kerak. Darhaqiqat, qancha sarlavha qo'shsangiz, biror narsa o'zgarganda shunchalik ko'p kodni qayta kompilyatsiya qilish kerak bo'ladi. Ushbu bog'liqliklarni cheklashning yaxshi usuli - bu sarlavha fayllarida juda tez-tez etarli bo'lgan oldingi deklaratsiyadan foydalanish (qarang: Men qachon oldinga deklaratsiyadan foydalanishim mumkin ?).
Google C++ uslubi bo‘yicha qo‘llanma, ismlar va qo‘shilish tartibi :
Asosiy maqsadi dir2/foo2.h-dagi narsalarni amalga oshirish yoki sinab ko'rish bo'lgan dir/foo.cc-da o'z ichiga quyidagilarni buyurtma qiling:
- dir2/foo2.h (afzal joylashuv - quyidagi tafsilotlarni ko'ring).
- C tizim fayllari.
- C++ tizim fayllari.
- Boshqa kutubxonalarning .h fayllari.
- Loyihangizning .h fayllari.
Men ularni alifbo tartibida buyurtma qilardim (topish osonroq)
"Qanday" aniq emas, balki "nima". Maqsadingiz sarlavha fayllarini kiritish tartibi hech qachon muhim emasligiga ishonch hosil qilishdir (va men "HECH QACHON!" Demoqchiman).
Ulardan faqat bittasini o'z ichiga olgan cpp fayllarini (har bir sarlavha fayli uchun bitta) yaratishda sarlavha fayllari kompilyatsiya qilinadimi yoki yo'qligini tekshirish yaxshi yordamdir.
.cpp fayllari uchun siz sinf sarlavhasini yoki birinchi bo'lib amalga oshirayotgan har qanday narsani kiritishingiz kerak, shuning uchun bu sarlavhada ba'zi o'z ichiga olishi mumkin bo'lmagan holatni tushunasiz. Shundan so'ng, kodlash bo'yicha ko'rsatmalar birinchi navbatda tizim sarlavhalarini, ikkinchidan loyiha sarlavhalarini o'z ichiga oladi, masalan, Google C++ uslubi bo‘yicha qo‘llanma.
Bu qaramlikdir va bu ko'p jihatdan sarlavhalarimizga nima qo'yganingizga bog'liq. Haqiqat shundaki, siz bu haqda haqiqatan ham mashhur bo'lishingiz va o'z qo'shimchalaringizni qat'iy saqlash uchun minimallashtirishingiz mumkin, ammo oxir-oqibat siz inklyuziya qo'riqchilaridan foydalanmoqchi bo'lgan stsenariyga duch kelasiz.
#ifndef MY_HEADER_H
#define MY_HEADER_H
//...
#endif
Muammo boshida unchalik ko'rinmaydi, lekin dasturiy ta'minotingizning murakkabligi oshib borishi bilan bog'liqliklaringiz o'sib boradi. Siz yaxshi ish qilishingiz va bu borada aqlli bo'lishingiz mumkin, lekin kattaroq C++ loyihalari odatda o'z ichiga oladi. Siz sinab ko'rishingiz mumkin, lekin siz faqat ko'p narsani qila olasiz. Shunday ekan, tirishqoq bo'ling va o'z tarkibingiz haqida o'ylang, HA! Lekin, albatta, bir nuqtada tsiklik bog'liqliklarga ega bo'lasiz va shuning uchun sizga qo'shimcha himoyachilar kerak.
Agar sarlavhaga boshqa sarlavhalar kerak bo'lsa, u ularni o'sha sarlavhaga o'z ichiga oladi.
Kodingizni tuzib ko'ring, shunda ko'rsatkichlar yoki havolalarni o'tkazing va qayerga yuborishingiz mumkinligini e'lon qiling.
Amalga oshirishda uni belgilaydigan sarlavha birinchi bo'lib ro'yxatga olinishi kerak (Visual Studio-dan tashqari, agar siz pch dan foydalansangiz, stdafx birinchi bo'ladi).
Men ularni odatda kerak bo'lganda ro'yxatlayman.
Men quyidagi konventsiyani eng foydali deb topdim:
module.cpp:
// this is the header used to trigger inclusion of precompiled headers
#include <precompiled.h>
// this ensures that anything that includes "module.h" works
#include "module.h"
// other headers, usually system headers, the project
Muhimi, modul sarlavhasini birinchi kompilyatsiya qilinmagan sarlavha sifatida qo'yishdir. Bu "module.h" ning kutilmagan bog'liqliklari yo'qligini ta'minlaydi.
Agar siz diskka kirish vaqti sekin bo'lgan katta loyiha ustida ishlayotgan bo'lsangiz, men ushbu uslubni qurish vaqtini qisqartirish uchun ishlatilganini ko'rdim:
module.cpp:
// this is the header used to trigger inclusion of precompiled headers
#include <precompiled.h>
// this ensures that anything that includes "module.h" works
#include "module.h"
// other headers, usually system headers, the project
#if !defined _OTHER_MODULE_GUARD_
#include "other_module.h"
#endif
#if !defined _ANOTHER_MODULE_GUARD_
#include "another_module.h"
#endif
Bu biroz mufassal, lekin diskda qidirishda tejash imkonini beradi, chunki sarlavha allaqachon kiritilgan bo'lsa, qidirilmaydi/ochilmaydi. Qo'riqchi tekshiruvisiz, kompilyator sarlavha faylini qidiradi va ochadi, butun faylni #ifdef
chiqarishni yakunlash uchun butun faylni tahlil qiladi.