C++ sarlavhasi tartibi [yopiq]

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?


person Konrad    schedule 05.03.2009    source manba


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.

person Mykola Golubyev    schedule 05.03.2009
comment
Menimcha, kerakli loyiha sarlavhalari ikkita element bo'yicha alohida bo'lishi kerak: - bitta lib dan loyiha sarlavhalari; - boshqa loyiha kutubxonalari sarlavhalari (ko'pincha loyiha kutubxonalari sarlavhalari ba'zi maxsus loyiha liblari sarlavhalariga qaraganda quyida joylashgan tartibda) - person bayda; 19.03.2009
comment
Menga sizning buyurtmangiz juda yoqadi. Shunday qilib, sarlavhalar o'zlarining bog'liqliklarini kiritish uchun boshqa sarlavhalarga tayanmaydi. - person fmuecke; 25.04.2012
comment
Qo'shilgan bayonotlarni takrorlashni oldini olish uchun har bir guruh ichida alifbo tartibida tartib bering. - person D Drmmr; 19.06.2018
comment
oldindan kompilyatsiya qilingan sarlavha birinchi bo'lishi kerak. - person Cfir TSabari; 20.09.2019

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.

person Daniel Earwicker    schedule 05.03.2009
comment
Buning o'rniga men buni birlik testlarida qilaman. - person Ferruccio; 05.03.2009
comment
Sinovni avtomatlashtirish osonroq: har bir sarlavha faylini (-c) kompilyatsiya qiling (ha, g++ -c blah.h) va uning kompilyatsiya qilinishiga ishonch hosil qiling. Keyin ob'ekt fayllarini tashlab yuborishingiz mumkin. - person Gilad Naor; 05.03.2009
comment
+1, bu javobda aytilmagan juda ko'p narsa bor. Ajoyib maslahat! - person John Leidegren; 05.03.2009
comment
Siz buni VC++ bilan ham qilishingiz mumkin: cl.exe /EHsc /TP /c blah.h - person Vadim Ferderer; 05.03.2009
comment
@VadimFerderer Afsuski, bu juda ko'p qo'shimcha yo'llar (o'z ichiga oladi, libs va boshqalar) bo'lgan murakkab loyihaning bir qismi bo'lgan sarlavha uchun ishlamaydi. cl.exe ni ushbu yo'llar haqida xabardor qilishning oson yo'li bormi (ular loyiha faylida o'rnatilgan). - person Rost; 18.02.2013

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 ?).

person Luc Touraille    schedule 05.03.2009
comment
O'z ichiga/sarlavha himoyachilari uchun +1. - person polarise; 14.10.2014

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.
person Igor Oks    schedule 05.03.2009
comment
Ha, lekin ggl uslubi bo'yicha qo'llanmada ba'zi yomon narsalar mavjud :) - person Matt Joiner; 22.10.2009

Men ularni alifbo tartibida buyurtma qilardim (topish osonroq)

person Gambrinus    schedule 05.03.2009
comment
Epic ham shunday qiladi, ularning Unreal Engine 4 uslubidagi hujjatida. - person ; 26.01.2015

"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.

person Benoît    schedule 05.03.2009

.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.

person Anteru    schedule 05.03.2009

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.

person John Leidegren    schedule 05.03.2009
comment
Bu "#pragma bir marta" deb chaqirish bilan bir xil emasmi? - person Konrad; 05.03.2009
comment
Ha, bu (ko'proq yoki kamroq) bir xil, lekin #pragma bir marta standart emas. - person Luc Touraille; 05.03.2009
comment
Yozuv uchun #pragma bir marta Microsoft kengaytmasi hisoblanadi. Agar men ko'p platformali loyiha ustida ishlayotgan bo'lsam, men uni qo'riqchilar bilan bir qatorda ishlataman, chunki #pragma bir marta faylni tahlil qilishning oldini oladi. - person Michael Kohne; 05.03.2009
comment
#pragma bir marta ko'pchilik C++ kompilyatorlarida, shu jumladan G++ da yaxshi ishlaydi. - person Matt Joiner; 22.10.2009

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.

person graham.reeds    schedule 05.03.2009

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.

person Skizz    schedule 05.03.2009