Kurz pojmenovaných modulů (C++)
Tento kurz se týká vytváření modulů C++20. Moduly nahrazují soubory hlaviček. Dozvíte se, jak moduly vylepšují soubory hlaviček.
V tomto kurzu se naučíte:
- Vytvoření a import modulu
- Vytvoření jednotky rozhraní primárního modulu
- Vytvoření souboru oddílu modulu
- Vytvoření souboru implementace jednotek modulu
Požadavky
Tento kurz vyžaduje Visual Studio 2022 17.1.0 nebo novější.
Při práci na příkladu kódu v tomto kurzu se můžou zobrazit chyby IntelliSense. Práce na modulu IntelliSense dohání kompilátor. Chyby IntelliSense je možné ignorovat a nezabrání sestavení příkladu kódu. Pokud chcete sledovat průběh práce IntelliSense, podívejte se na tento problém.
Co jsou moduly C++
Soubory hlaviček jsou způsob sdílení deklarací a definic mezi zdrojovými soubory v jazyce C++. Soubory hlaviček jsou křehké a obtížně se vytváří. Můžou se kompilovat jinak v závislosti na pořadí, ve které je zahrnete, nebo na makrech, která jsou nebo nejsou definována. Můžou zpomalit dobu kompilace, protože se znovu zpracovávají pro každý zdrojový soubor, který je obsahuje.
C++20 představuje moderní přístup ke komponentizaci programů C++: modulů.
Podobně jako soubory hlaviček umožňují moduly sdílet deklarace a definice napříč zdrojovými soubory. Na rozdíl od souborů hlaviček ale moduly nevracely definice maker ani podrobnosti privátní implementace.
Moduly se snadněji vytváří, protože jejich sémantika se nemění kvůli definicím maker nebo k importu, pořadí importů atd. Usnadňují také kontrolu nad tím, co je viditelné pro uživatele.
Moduly poskytují dodatečné bezpečnostní záruky, že soubory hlaviček ne. Kompilátor a linker spolupracují, aby se zabránilo možným problémům se kolizemi názvů, a poskytuje silnější záruky jednoho pravidla definice (ODR).
Model silného vlastnictví zabraňuje konfliktům mezi názvy v době propojení, protože linker připojí exportované názvy k modulu, který je exportuje. Tento model umožňuje kompilátoru jazyka Microsoft Visual C++ zabránit nedefinovanému chování způsobenému propojením různých modulů, které hlásí podobné názvy ve stejném programu. Další informace naleznete v tématu Silné vlastnictví.
Modul se skládá z jednoho nebo více souborů zdrojového kódu zkompilovaných do binárního souboru. Binární soubor popisuje všechny exportované typy, funkce a šablony v modulu. Když zdrojový soubor importuje modul, kompilátor načte v binárním souboru, který obsahuje obsah modulu. Čtení binárního souboru je mnohem rychlejší než zpracování souboru hlavičky. Binární soubor je také znovu použit kompilátorem při každém importu modulu, což šetří ještě více času. Vzhledem k tomu, že se modul sestavuje jednou a ne pokaždé, když se importuje, může se čas sestavení zkrátit, někdy výrazně.
Důležitější je, že moduly nemají problémy s křehkostí, které soubory hlaviček dělají. Import modulu nemění sémantiku modulu ani sémantiku jakéhokoli jiného importovaného modulu. Makra, direktivy preprocesoru a neexportované názvy deklarované v modulu nejsou viditelné pro zdrojový soubor, který ho importuje. Moduly můžete importovat v libovolném pořadí a nezměníte význam modulů.
Moduly lze používat vedle souborů hlaviček. Tato funkce je vhodná, pokud migrujete základ kódu tak, aby používal moduly, protože to můžete udělat ve fázích.
V některých případech lze soubor hlavičky importovat jako jednotku záhlaví, nikoli jako #include
soubor. Jednotky hlaviček jsou doporučenou alternativou k předkompilovaným souborům hlaviček (PCH). Snadněji se nastavují a používají než sdílené soubory PCH , ale poskytují podobné výhody výkonu. Další informace naleznete v tématu Návod: Sestavení a import jednotek hlaviček v sadě Microsoft Visual C++.
Váš kód může automaticky využívat moduly ve stejném projektu nebo jakékoli odkazované projekty pomocí odkazů na projekty typu projekt-projekt na statické knihovny.
Vytvoření projektu
Při vytváření jednoduchého projektu se podíváme na různé aspekty modulů. Projekt implementuje rozhraní API pomocí modulu místo souboru hlavičky.
V sadě Visual Studio 2022 nebo novější zvolte Vytvořit nový projekt a potom typ projektu Konzolová aplikace (pro C++). Pokud tento typ projektu není k dispozici, možná jste při instalaci sady Visual Studio nevybrali vývoj desktopových aplikací pomocí úlohy C++ . Pomocí Instalační program pro Visual Studio můžete přidat úlohu C++.
Pojmenujte nový projekt ModulesTutorial
a vytvořte projekt.
Vzhledem k tomu, že moduly jsou funkce C++20, použijte možnost nebo/std:c++latest
možnost kompilátoru/std:c++20
. V Průzkumník řešení klikněte pravým tlačítkem myši na název ModulesTutorial
projektu a pak zvolte Vlastnosti. V dialogovém okně Stránky vlastností projektu změňte konfiguraci na Všechny konfigurace a platformy na všechny platformy. V podokně stromového zobrazení vlevo vyberte Obecné vlastnosti>konfigurace. Vyberte vlastnost Standard jazyka C++. Pomocí rozevíracího seznamu změňte hodnotu vlastnosti na STANDARD ISO C++20 (/std:c++20). Pokud chcete změnu přijmout, vyberte OK .
Vytvoření jednotky rozhraní primárního modulu
Modul se skládá z jednoho nebo více souborů. Jeden z těchto souborů musí být to, co se nazývá primární jednotka rozhraní modulu. Definuje, co modul exportuje; to znamená, jaké dovozce modulu uvidí. Pro každý modul může existovat pouze jedna jednotka rozhraní primárního modulu.
Pokud chcete přidat primární jednotku rozhraní modulu, klikněte v Průzkumník řešení pravým tlačítkem na Zdrojové soubory a pak vyberte Přidat>modul.
V dialogovém okně Přidat novou položku , které se zobrazí, zadejte název BasicPlane.Figures.ixx
nového modulu a zvolte Přidat.
Výchozí obsah vytvořeného souboru modulu má dva řádky:
export module BasicPlane;
export void MyFunc();
Klíčová export module
slova na prvním řádku deklarují, že tento soubor je jednotkou rozhraní modulu. Tady je malý bod: pro každý pojmenovaný modul musí být přesně jedna jednotka rozhraní modulu bez zadaného oddílu modulu. Tato jednotka modulu se nazývá primární jednotka rozhraní modulu.
Primární jednotka rozhraní modulu je místo, kde deklarujete funkce, typy, šablony, další moduly a oddíly modulů, které se zpřístupní při importu zdrojových souborů. Modul se může skládat z více souborů, ale pouze soubor rozhraní primárního modulu identifikuje, co se má zveřejnit.
BasicPlane.Figures.ixx
Obsah souboru nahraďte následujícím kódem:
export module BasicPlane.Figures; // the export module keywords mark this file as a primary module interface unit
Tento řádek identifikuje tento soubor jako primární rozhraní modulu a dává modulu název: BasicPlane.Figures
. Tečka v názvu modulu nemá pro kompilátor žádný zvláštní význam. Pomocí období můžete sdělit, jak je modul uspořádaný. Pokud máte více souborů modulů, které spolupracují, můžete použít tečky k označení oddělení obav. V tomto kurzu použijeme tečky k označení různých funkčních oblastí rozhraní API.
Tento název je také tam, odkud pochází "pojmenovaný" v "pojmenovaném modulu". Soubory, které jsou součástí tohoto modulu, používají tento název k tomu, aby se identifikovaly jako součást pojmenovaného modulu. Pojmenovaný modul je kolekce jednotek modulů se stejným názvem modulu.
Měli bychom si promluvit o rozhraní API, které budeme implementovat ještě chvíli, než budeme pokračovat. Má vliv na volby, které provedeme v dalším kroku. Rozhraní API představuje různé obrazce. V tomto příkladu poskytneme pouze několik obrazců: Point
a Rectangle
. Point
je určen k použití jako součást složitějších obrazců, například Rectangle
.
Abychom si ukázali některé funkce modulů, zabereme toto rozhraní API do částí. Jednou z nich bude Point
rozhraní API. Druhá část bude Rectangle
. Představte si, že toto rozhraní API se rozšíří do něčeho složitějšího. Rozdělení je užitečné pro oddělení problémů nebo usnadnění údržby kódu.
Zatím jsme vytvořili primární rozhraní modulu, které toto rozhraní API zveřejní. Point
Teď vytvoříme rozhraní API. Chceme, aby byl součástí tohoto modulu. Z důvodů logické organizace a potenciální efektivity sestavení chceme tuto část rozhraní API snadno pochopit sami. K tomu vytvoříme soubor oddílu modulu.
Soubor oddílu modulu je kus nebo součást modulu. To, co je jedinečné, je, že může být považováno za jednotlivou část modulu, ale pouze v rámci modulu. Oddíly modulů nelze využívat mimo modul. Oddíly modulů jsou užitečné pro rozdělení implementace modulu na spravovatelné části.
Při importu oddílu do primárního modulu se všechny jeho deklarace zobrazí primárnímu modulu bez ohledu na to, jestli se exportují. Oddíly je možné importovat do libovolného rozhraní oddílů, primárního rozhraní modulu nebo jednotky modulu, které patří do pojmenovaného modulu.
Vytvoření souboru oddílu modulu
Point
oddíl modulu
Pokud chcete vytvořit soubor oddílu modulu, klikněte v Průzkumník řešení pravým tlačítkem na Zdrojové soubory a pak vyberte Přidat>modul. Pojmenujte soubor BasicPlane.Figures-Point.ixx
a zvolte Přidat.
Protože se jedná o soubor oddílu modulu, přidali jsme do názvu modulu pomlčka a název oddílu. Tato konvence pomáhá kompilátoru v případě příkazového řádku, protože kompilátor používá pravidla vyhledávání názvů na základě názvu modulu k vyhledání zkompilovaného .ifc
souboru pro oddíl. Tímto způsobem nemusíte zadávat explicitní /reference
argumenty příkazového řádku, abyste našli oddíly, které patří do modulu. Je také užitečné uspořádat soubory, které patří do modulu podle názvu, protože můžete snadno zjistit, které soubory patří do kterých modulů.
Nahraďte obsah BasicPlane.Figures-Point.ixx
tímto obsahem:
export module BasicPlane.Figures:Point; // defines a module partition, Point, that's part of the module BasicPlane.Figures
export struct Point
{
int x, y;
};
Soubor začíná export module
na . Tato klíčová slova jsou také tím, jak začíná rozhraní primárního modulu. Čím se tento soubor liší, je dvojtečka (:
) za názvem modulu, za kterým následuje název oddílu. Tato konvence vytváření názvů identifikuje soubor jako oddíl modulu. Protože definuje rozhraní modulu pro oddíl, nepovažuje se za primární rozhraní modulu.
Název BasicPlane.Figures:Point
identifikuje tento oddíl jako součást modulu BasicPlane.Figures
. (Nezapomeňte, že tečka v názvu nemá žádný zvláštní význam pro kompilátor). Dvojtečka označuje, že tento soubor obsahuje oddíl modulu s názvem Point
, který patří do modulu BasicPlane.Figures
. Tento oddíl můžeme importovat do jiných souborů, které jsou součástí tohoto pojmenovaného modulu.
V tomto souboru export
se struct Point
klíčové slovo zpřístupní příjemcům.
Rectangle
oddíl modulu
Dalším oddílem, který definujeme, je Rectangle
. Vytvořte jiný soubor modulu stejným postupem jako předtím: V Průzkumník řešení klikněte pravým tlačítkem na Zdrojové soubory a pak vyberte Přidat>modul. Pojmenujte soubor BasicPlane.Figures-Rectangle.ixx
a vyberte Přidat.
Nahraďte obsah BasicPlane.Figures-Rectangle.ixx
tímto obsahem:
export module BasicPlane.Figures:Rectangle; // defines the module partition Rectangle
import :Point;
export struct Rectangle // make this struct visible to importers
{
Point ul, lr;
};
// These functions are declared, but will
// be defined in a module implementation file
export int area(const Rectangle& r);
export int height(const Rectangle& r);
export int width(const Rectangle& r);
Soubor začíná export module BasicPlane.Figures:Rectangle;
deklarací oddílu modulu, který je součástí modulu BasicPlane.Figures
. Přidané :Rectangle
do názvu modulu ho definuje jako oddíl modulu BasicPlane.Figures
. Dá se importovat jednotlivě do libovolného souboru modulu, který je součástí tohoto pojmenovaného modulu.
Dále ukazuje, import :Point;
jak importovat oddíl modulu. Tento import
příkaz zviditelní všechny exportované typy, funkce a šablony v oddílu modulu. Nemusíte zadávat název modulu. Kompilátor ví, že tento soubor patří do BasicPlane.Figures
modulu kvůli export module BasicPlane.Figures:Rectangle;
horní části souboru.
Dále kód exportuje definici struct Rectangle
a deklarace některých funkcí, které vracejí různé vlastnosti obdélníku. Klíčové export
slovo označuje, jestli se má předcházet tomu, co předchází příjemcům modulu. Používá se k tomu, aby byly funkce area
, height
a width
viditelné mimo modul.
Všechny definice a deklarace v oddílu modulu jsou viditelné pro jednotku importujícího modulu bez ohledu na export
to, jestli mají klíčové slovo nebo ne. Klíčové export
slovo určuje, jestli bude definice, deklarace nebo typedef viditelná mimo modul při exportu oddílu v primárním rozhraní modulu.
Názvy se uživatelům modulu zviditelní několika způsoby:
- Klíčové slovo
export
umístěte před každý typ, funkci a tak dále, které chcete exportovat. - Pokud jste například umístili
export
před obor názvůexport namespace N { ... }
, vše definované ve složených závorkách se exportuje. Pokud ale v modulu, který definujetenamespace N { struct S {...};}
struct S
, není k dispozici pro uživatele modulu. Není k dispozici, protože deklarace oboru názvů není předzvěděnáexport
, i když existuje jiný obor názvů se stejným názvem, který je. - Pokud typ, funkce atd., neměl by být exportován, vynechat
export
klíčové slovo. Zobrazí se ostatním souborům, které jsou součástí modulu, ale ne pro dovozce modulu. - Slouží
module :private;
k označení začátku oddílu privátního modulu. Oddíl soukromého modulu je oddíl modulu, ve kterém jsou deklarace viditelné pouze pro daný soubor. Nejsou viditelné pro soubory, které tento modul importují, ani do jiných souborů, které jsou součástí tohoto modulu. Představte si ho jako oddíl, který je pro soubor statický. Tento oddíl je viditelný pouze v rámci souboru. - Pokud chcete, aby byl importovaný modul nebo oddíl modulu viditelný, použijte
export import
. Příklad je uvedený v další části.
Vytvoření oddílů modulu
Když teď máme dvě části rozhraní API definované, pojďme je spojit, abychom k nim mohli přistupovat jako k souborům, které tento modul importují.
Všechny oddíly modulu musí být zpřístupněny jako součást definice modulu, do které patří. Oddíly se zveřejňují v rozhraní primárního modulu. BasicPlane.Figures.ixx
Otevřete soubor, který definuje primární rozhraní modulu. Nahraďte jeho obsah následujícím kódem:
export module BasicPlane.Figures; // keywords export module marks this as a primary module interface unit
export import :Point; // bring in the Point partition, and export it to consumers of this module
export import :Rectangle; // bring in the Rectangle partition, and export it to consumers of this module
Dva řádky, které začínají export import
, jsou tady nové. Když se takto zkombinují, dávají kompilátoru pokyn, aby importoval zadaný modul a aby byl viditelný pro uživatele tohoto modulu. V tomto případě dvojtečka (:
) v názvu modulu označuje, že importujeme oddíl modulu.
Importované názvy neobsahují úplný název modulu. Například :Point
oddíl byl deklarován jako export module BasicPlane.Figures:Point
. Ale tady importujeme :Point
. Vzhledem k tomu, že jsme v souboru rozhraní primárního modulu pro modul BasicPlane.Figures
, je název modulu implicitní a je zadán pouze název oddílu.
Zatím jsme definovali primární rozhraní modulu, které zpřístupňuje rozhraní API, které chceme zpřístupnit. Ale deklarovali jsme pouze, nedefinovali, area()
height()
nebo width()
. Provedeme to dále vytvořením souboru implementace modulu.
Vytvoření souboru implementace jednotek modulu
Soubory implementace jednotek modulu nekončí příponou .ixx
– jsou to normální .cpp
soubory. Přidejte soubor implementace jednotek modulu tak, že vytvoříte zdrojový soubor kliknutím pravým tlačítkem v Průzkumník řešení ve zdrojových souborech, vyberte Přidat>novou položku a pak vyberte Soubor C++ (.cpp). Pojmenujte nový soubor BasicPlane.Figures-Rectangle.cpp
a pak zvolte Přidat.
Zásady vytváření názvů pro implementační soubor oddílu modulu se řídí konvencí pojmenování oddílu. Má ale příponu .cpp
, protože se jedná o implementační soubor.
BasicPlane.Figures-Rectangle.cpp
Obsah souboru nahraďte následujícím kódem:
module;
// global module fragment area. Put #include directives here
module BasicPlane.Figures:Rectangle;
int area(const Rectangle& r) { return width(r) * height(r); }
int height(const Rectangle& r) { return r.ul.y - r.lr.y; }
int width(const Rectangle& r) { return r.lr.x - r.ul.x; }
Tento soubor začíná module;
tím, že představuje zvláštní oblast modulu označovanou jako globální fragment modulu. Předchází kódu pro pojmenovaný modul a je tam, kde můžete použít direktivy preprocesoru, jako #include
je . Kód v globálním fragmentu modulu není vlastněný ani exportován rozhraním modulu.
Pokud zahrnete hlavičkový soubor, obvykle nechcete, aby se s ním zacházelo jako s exportovanou částí modulu. Soubor hlaviček obvykle zahrnete jako podrobnosti implementace, které by neměly být součástí rozhraní modulu. Může se jednat o pokročilé případy, kdy to chcete udělat, ale obecně ne. Pro direktivy globálního fragmentu modulu nejsou generována #include
žádná samostatná metadata (.ifc
soubory). Globální fragmenty modulů poskytují vhodné místo pro zahrnutí souborů hlaviček, jako windows.h
jsou , nebo v Linuxu, unistd.h
.
Soubor implementace modulu, který vytváříme, neobsahuje žádné knihovny, protože je nepotřebuje jako součást jeho implementace. Ale pokud ano, tato oblast je místo, kde by #include
direktivy jdou.
Řádek module BasicPlane.Figures:Rectangle;
označuje, že tento soubor je součástí pojmenovaného modulu BasicPlane.Figures
. Kompilátor do tohoto souboru automaticky přenese typy a funkce vystavené rozhraním primárního modulu. Jednotka implementace modulu nemá export
klíčové slovo před klíčovým slovem module
v deklaraci modulu.
Dále jsou definice funkcí area()
, height()
a width()
. Byly deklarovány v oddílu Rectangle
v BasicPlane.Figures-Rectangle.ixx
. Vzhledem k tomu, že primární rozhraní modulu pro tento modul importoval Point
oddíly a Rectangle
oddíly modulu, jsou tyto typy viditelné zde v souboru implementace jednotek modulu. Zajímavá funkce jednotek implementace modulu: Kompilátor automaticky zviditelní vše v odpovídajícím primárním rozhraní modulu pro soubor. Není potřeba.imports <module-name>
Cokoli, co deklarujete v rámci implementační jednotky, je viditelné pouze pro modul, ke kterému patří.
Import modulu
Teď použijeme modul, který jsme definovali. Otevřete soubor ModulesTutorial.cpp
. Byl vytvořen automaticky jako součást projektu. V současné době obsahuje funkci main()
. Nahraďte jeho obsah následujícím kódem:
#include <iostream>
import BasicPlane.Figures;
int main()
{
Rectangle r{ {1,8}, {11,3} };
std::cout << "area: " << area(r) << '\n';
std::cout << "width: " << width(r) << '\n';
return 0;
}
Tento příkaz import BasicPlane.Figures;
zviditelňuje všechny exportované funkce a typy z BasicPlane.Figures
modulu pro tento soubor. Může přijít před nebo po jakýchkoli #include
direktivách.
Aplikace pak pomocí typů a funkcí z modulu vypíše oblast a šířku definovaného obdélníku:
area: 50
width: 10
Anatomie modulu
Teď se podrobněji podíváme na různé soubory modulů.
Rozhraní primárního modulu
Modul se skládá z jednoho nebo více souborů. Jeden z nich definuje rozhraní, které uvidí dovozci. Tento soubor obsahuje rozhraní primárního modulu. Pro každý modul může existovat pouze jedno primární rozhraní modulu. Jak už bylo uvedeno dříve, jednotka rozhraní exportovaného modulu nezadá oddíl modulu.
Ve výchozím nastavení má .ixx
rozšíření. Zdrojový soubor ale můžete považovat za soubor rozhraní modulu s libovolnou příponou. Uděláte to tak, že na kartě Upřesnit nastavíte vlastnost Compile As (Kompilace jako) na stránce vlastností zdrojového souboru na hodnotu Compile As Module (/interface):
Základní osnova definičního souboru rozhraní modulu je:
module; // optional. Defines the beginning of the global module fragment
// #include directives go here but only apply to this file and
// aren't shared with other module implementation files.
// Macro definitions aren't visible outside this file, or to importers.
// import statements aren't allowed here. They go in the module preamble, below.
export module [module-name]; // Required. Marks the beginning of the module preamble
// import statements go here. They're available to all files that belong to the named module
// Put #includes in the global module fragment, above
// After any import statements, the module purview begins here
// Put exported functions, types, and templates here
module :private; // optional. The start of the private module partition.
// Everything after this point is visible only within this file, and isn't
// visible to any of the other files that belong to the named module.
Tento soubor musí začínat buď module;
tím, že označuje začátek globálního fragmentu modulu, nebo export module [module-name];
musí indikovat začátek modulu purview.
Purview modulu je místo, kde funkce, typy, šablony atd., jdou z modulu zpřístupnit.
Můžete také vystavit další moduly nebo oddíly modulů prostřednictvím export import
klíčových slov, jak je znázorněno BasicPlane.Figures.ixx
v souboru.
Primární soubor rozhraní musí exportovat všechny oddíly rozhraní definované pro modul přímo nebo nepřímo nebo program je špatně vytvořený.
Oddíl soukromého modulu je místo, kde můžete dát věci, které chcete zobrazit pouze v tomto souboru.
Modulové jednotky rozhraní předchází klíčovému slovu module
klíčovým slovem export
.
Podrobnější informace o syntaxi modulu najdete v tématu Moduly.
Jednotky implementace modulu
Jednotky implementace modulu patří do pojmenovaného modulu. Pojmenovaný modul, do který patří, je označen příkazem module [module-name]
v souboru. Jednotky implementace modulu poskytují podrobnosti implementace, které z hygieny kódu nebo z jiných důvodů nechcete vložit do primárního rozhraní modulu nebo do souboru oddílu modulu.
Jednotky implementace modulu jsou užitečné pro rozdělení velkého modulu na menší části, což může vést k rychlejším sestavením. Tato technika je stručně popsaná v části Osvědčené postupy .
Soubory jednotek implementace modulu mají příponu .cpp
. Základní osnova souboru jednotky implementace modulu je:
// optional #include or import statements. These only apply to this file
// imports in the associated module's interface are automatically available to this file
module [module-name]; // required. Identifies which named module this implementation unit belongs to
// implementation
Soubory oddílů modulu
Oddíly modulů poskytují způsob, jak modul integrovat do různých částí nebo oddílů. Oddíly modulů se mají importovat jenom v souborech, které jsou součástí pojmenovaného modulu. Nedají se importovat mimo pojmenovaný modul.
Oddíl má soubor rozhraní a nula nebo více implementačních souborů. Oddíl modulu sdílí vlastnictví všech deklarací v celém modulu.
Všechny názvy exportované soubory rozhraní oddílů musí být importovány a znovu exportovány (export import
) souborem primárního rozhraní. Název oddílu musí začínat názvem modulu, za kterým následuje dvojtečka a pak název oddílu.
Základní přehled souboru rozhraní oddílu vypadá takto:
module; // optional. Defines the beginning of the global module fragment
// This is where #include directives go. They only apply to this file and aren't shared
// with other module implementation files.
// Macro definitions aren't visible outside of this file or to importers
// import statements aren't allowed here. They go in the module preamble, below
export module [Module-name]:[Partition name]; // Required. Marks the beginning of the module preamble
// import statements go here.
// To access declarations in another partition, import the partition. Only use the partition name, not the module name.
// For example, import :Point;
// #include directives don't go here. The recommended place is in the global module fragment, above
// export imports statements go here
// after import, export import statements, the module purview begins
// put exported functions, types, and templates for the partition here
module :private; // optional. Everything after this point is visible only within this file, and isn't
// visible to any of the other files that belong to the named module.
...
Osvědčené postupy pro moduly
Modul a kód, který importuje, musí být zkompilovány se stejnými možnostmi kompilátoru.
Pojmenování modulů
- V názvech modulů můžete použít tečky (.), ale nemají pro kompilátor žádný zvláštní význam. Použijte je k vyjádření významu uživatelům vašeho modulu. Začněte například s knihovnou nebo hlavním oborem názvů projektu. Dokončete název, který popisuje funkce modulu.
BasicPlane.Figures
má vyjádřit rozhraní API pro geometrické roviny a konkrétně obrázky, které lze reprezentovat v rovině. - Název souboru, který obsahuje primární rozhraní modulu, je obecně název modulu. Například vzhledem k názvu
BasicPlane.Figures
modulu by název souboru obsahujícího primární rozhraní byl pojmenovánBasicPlane.Figures.ixx
. - Název souboru oddílu modulu je obvykle
<primary-module-name>-<module-partition-name>
tam, kde za ním následuje pomlčka (-) a název oddílu. NapříkladBasicPlane.Figures-Rectangle.ixx
Pokud vytváříte z příkazového řádku a používáte tuto konvenci vytváření názvů pro oddíly modulu, nemusíte explicitně přidávat /reference
pro každý soubor oddílů modulu. Kompilátor je vyhledá automaticky na základě názvu modulu. Název zkompilovaného souboru oddílu (končící příponou .ifc
) se vygeneruje z názvu modulu. Vezměte v úvahu název BasicPlane.Figures:Rectangle
modulu: kompilátor očekává, že odpovídající zkompilovaný soubor oddílu pro Rectangle
název BasicPlane.Figures-Rectangle.ifc
. Kompilátor používá toto schéma pojmenování, aby bylo snazší používat oddíly modulů tím, že automaticky vyhledá soubory jednotek rozhraní pro oddíly.
Můžete je pojmenovat pomocí vlastní konvence. Pak ale budete muset zadat odpovídající /reference
argumenty kompilátoru příkazového řádku.
Moduly faktoru
Za účelem snadnější údržby kódu a potenciálně rychlejší kompilace použijte implementační soubory a oddíly modulu.
Například přesunutí implementace modulu z definičního souboru rozhraní modulu a do souboru implementace modulu znamená, že změny implementace nemusí nutně způsobit, že každý soubor, který importuje modul znovu kompilovat (pokud nemáte inline
implementace).
Oddíly modulů usnadňují logické faktorování velkého modulu. Dají se použít ke zlepšení doby kompilace, aby změny části implementace nezpůsobily rekompilování všech souborů modulu.
Shrnutí
V tomto kurzu jste se seznámili se základy modulů C++20. Vytvořili jste primární rozhraní modulu, definovali jste oddíl modulu a vytvořili jste soubor implementace modulu.
Viz také
Přehled modulů v jazyce C++
module
, import
, export
klíčová slova
Prohlídka modulů C++ v sadě Visual Studio
Praktické moduly C++20 a budoucnost nástrojů kolem modulů C++
Přesunutí projektu do modulů s názvem C++
Návod: Sestavení a import jednotek hlaviček v Microsoft Visual C++
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro