Vkládání hlavičkových souborů v knihovně – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Vkládání hlavičkových souborů v knihovně – C / C++ – Fórum – Programujte.comVkládání hlavičkových souborů v knihovně – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Lorin0
Návštěvník
2. 7. 2012   #1
-
0
-

Ahoj. Snažím se vytvořit jednoduchou knihovnu pro C++ v řádu desítky souborů. Každá třída je uložena v samostatném souboru, soubory jsou roztříděny do několika adresářů. 

Každá třída využívá několik hlavičkových souborů. Ty, které využije jen daná třída (popřípadě ještě jedna, či dvě), vkládám (#include) přímo do hlavičkových souborů dané třídy. Problém je s hlavičkovými soubory, které využívám ve většině tříd (string, iostream, a další). Nechce se mi je psát ke každé třídě, protože nechci několikrát načítat jednu a tu samou věc. 

Jak se v tomto případě postupuje?

1) Napadlo mě vytvořit jeden hlavičkový soubor, který by každá třída includovala. To ale nic neřeší, naopak se přidává další soubor, který je potřeba načíst.

2) Druhý nápad bylo vytvoření jednoho "hlavního" hlavičkového souboru, který by do sebe includoval potřebné C++ knihovny (již zmíněný string, iostream, ...). Tento hlavičkový soubor by se v projektu, který by knihovnu využíval, musel uvést jako první (první by se přidal pomocí Include) a ostatní hlavičkové soubory by z něj jen čerpaly (vše potřebné by již bylo vloženo).

3) A poslední možností je nechat vše na uživateli a starat se jen o nestandardní knihovny, které se většinou neincludují (zmínkou třeba boost). String a iostream by musel includovat do svého projektu sám uživatel.


Jak s druhým, tak s posledním případem mám problémy. Nedokážu donutit překladač (používám g++ 4.4.5), aby ignoroval chyby z neincludování potřebných hlavičkových souborů.

Díky za nápady, Lorin

Nahlásit jako SPAM
IP: 89.190.72.–
yaqwsx+9
Posthunter
2. 7. 2012   #2
-
0
-

Nechce se mi je psát ke každé třídě, protože nechci několikrát načítat jednu a tu samou věc.

Pokud je skutečně toto tvůj problém, tak mám pro tebe dobrou zprávu - nemusíš to řešit. Nic se víckrát nenačítá, objem výsledného programu neroste - tohle si překladač pohlídá.

Nahlásit jako SPAM
IP: 85.160.59.–
Life is too short to remove USB mass storage safely...
Správný drsňák udělá z konzole cokoliv
ingiraxo+15
Grafoman
2. 7. 2012   #3
-
0
-

Jak napsal yaqwsx, tak to neřeš, ale doporučuju do každé hlavičky dát před všechny includy (na 1.řádek) #pragma once, ten ti zajistí, že nedojte k načtení hlavičky víckrát než jednou (lze to řešit i přes "IFy" (makra))

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
Lorin0
Návštěvník
2. 7. 2012   #4
-
0
-

#3 ingiraxo 

Ve mnou psaných hlavičkových souborech používám kombinaci #ifndef, #define, #endif,#pragma once je použitelné jen pro Visual Studio ne? 

#2 yaqwsx
Proč se tedy používají výše zmíněné makra, když si vše hlídá překladač? Je to nějaký přežitek z dob, kdy to nebylo u překladačů standardem? 

----

Takže ve výsledku můžu do každého (mnou psaného) hlavičkového souboru includovat co chci a jestliže jsem to již includoval dříve, nic se přidávat nebude?

Nahlásit jako SPAM
IP: 89.190.72.–
yaqwsx+9
Posthunter
2. 7. 2012   #5
-
0
-

#4 Lorin
Překladač hlídá vícenásobné vložení funkcí do výsledného binárního (spustitelného souboru) - z tvého dotazu jsem měl pocit, že se bojíš tohoto, resp. že se při spuštění aplikace do paměti RAM natáhne např. kód třídy string 4×.

Hlavičkové soubory, resp. jakýkoliv soubor, který je includován, musí být ošetřen pomocí #pragma once. Jinak by ti překladač hlásil vícenásobné definice. Pokud chceš mít v této věci jasno, doporučuji si nastudovat jak funguje toolchain (co dělá preprocesor, kompilátor a linker).

#pragam once bylo poprvé ve VS, ale již pár let jej podporuje i gcc. Dokonce tuším, že bylo přidáno i do nevého standardu C++x11

Nahlásit jako SPAM
IP: 85.160.59.–
Life is too short to remove USB mass storage safely...
Správný drsňák udělá z konzole cokoliv
Lorin0
Návštěvník
2. 7. 2012   #6
-
0
-

#5 yaqwsx

Překladač hlídá vícenásobné vložení funkcí do výsledného binárního (spustitelného souboru)

O tom vím. 

#pragma once

Dejme tomu, že by gcc podporovalo #pragma once. Nezamezuje pragma jen tomu, aby mnou vytvořený hlavičkový soubor byl includován několikrát? Jestliže ano, mou situaci to myslím neřeší. Chci zabránit vícenásobnému vkládání cizích hlavičkových souborů. Příklad:

 knihovna.hpp

// hlavickovy soubor knihovna.hpp
#include "nejaky_soubor.h"
#include "nejaky_dalsi_soubor_h"
#include <string>

class test {
	private: 
		// ...
	public:
		// ...
};

knihovna2.hpp

// hlavickovy soubor knihovna2.hpp
#include "nejaky_soubor.h"
#include <string>

class test2 {
	private:
		// ...
	public:
		// ..
};

main.cpp

// hlavni soubor
#include <iostream>
#include "knihovna.hpp"
#include "knihovna2.hpp"

int main(int argc, char **argv) {
	// ...
}

Jak je vidět, hlavičkový soubor knihovna.hpp i knihovna2.hpp includují nejaky_soubor.h. Já chci zamezit tomu, aby se tento soubor vkládal 2x.

Nahlásit jako SPAM
IP: 89.190.72.–
vitamin+8
Grafoman
2. 7. 2012   #7
-
0
-

 pouzi:

#ifndef KNIHOVNA_HPP_

#define KNIHOVNA_HPP_

/* tvoj kod ktory sa ma v module nachadzat len 1 krat*/

#endif

alebo ten #pragma once

includy funguju tak ako keby si na miesto konkretneho includu dosadil obsah includovaneho suboru.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Lorin0
Návštěvník
2. 7. 2012   #8
-
0
-

Jestli jsem to pochopil správně, musím kolem includů (které se opakují a nechci je načítat vícekrát) dát kombinaci maker preprocesoru #ifndef, #define a #endif?

#ifndef KNIHOVNA_H
#define KNIHOVNA_H

	#ifndef KNIHOVNA_string
		#define KNIHOVNA_string
		#include <string>
	#endif

	#ifndef KNIHOVNA_sstream
		#define KNIHOVNA_sstream
		#include <sstream>
	#endif 

	// ... samotný obsah hlavičkového souboru
#endif
Nahlásit jako SPAM
IP: 89.190.72.–
ingiraxo+15
Grafoman
2. 7. 2012   #9
-
0
-

#6 Lorin
To to chceš vyřešit se v praxi vůbec neřeší... Obě tyto třídy (z té tvoji ukázky) potřebují hlavičku, takže ji prostě includneš, aby si ji mohl použít.. vůbec se nemusíš bát ničeho, takto se to dělá normálně (za předpokladu, že v každé hlavičce máš #pragma once, jinak ti to hodí redefinice tušim)

Jinak to co psal vitamin, #pragma once je jen zprácenej zápis ifndef-define-endif, ten ti zajišťuje, že se hlavička natáhne jen jednou

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
Lorin0
Návštěvník
2. 7. 2012   #10
-
0
-

Takže to, že budu v několika hlavičkových souborech includovat stejné hlavičkové soubory (SDL, Allegro, boost, ...), ničemu nevadí?

Nahlásit jako SPAM
IP: 89.190.72.–
Řešení
KIIV
~ Moderátor
+43
God of flame
2. 7. 2012   #11
-
0
-
Vyřešeno Nejlepší odpověď

#10 Lorin
jediny cemu to vadi jsou vlastni hlavicky, kde zapomenes na to vynechani v pripade ze makro existuje...

jediny co se v praxi resi je omezit zbytecne hlavickove soubory co se nevyuzivaji ... tj. includovat jen to co je potreba (dost to zpomaluje samotnou kompilaci, kdyz je tam stovka hlavicek ale potrebujes jen 3... )

a nekdy se musi resit u vlastnich veci zavislosti... poradi includu a cross reference ...

Nahlásit jako SPAM
IP: 62.245.85.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Lorin0
Návštěvník
2. 7. 2012   #12
-
0
-

Díky za pomoc.

Nahlásit jako SPAM
IP: 89.190.72.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 40 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý