Sdílet prostřednictvím


Rozsah (C++)

Když deklarujete prvek programu, jako je třída, funkce nebo proměnná, jeho název může být "vidět" a použit pouze v určitých částech programu. Kontext, ve kterém je název viditelný, se nazývá jeho obor. Pokud například deklarujete proměnnou x v rámci funkce, x je viditelná pouze v těle této funkce. Má místní rozsah. V programu můžete mít jiné proměnné se stejným názvem; pokud jsou v různých oborech, neporušují pravidlo jedné definice a nevyvolají se žádná chyba.

Pro automatické nestatické proměnné obor také určuje, kdy jsou vytvořeny a zničeny v paměti programu.

Existuje šest druhů rozsahu:

  • Globální obor A globální název je ten, který je deklarován mimo jakoukoli třídu, funkci nebo obor názvů. V jazyce C++ však existují i tyto názvy s implicitní globální obor názvů. Rozsah globálních názvů se vztahuje od bodu deklarace na konec souboru, ve kterém jsou deklarovány. U globálních názvů se viditelnost řídí také pravidly propojení , která určují, jestli je název viditelný v jiných souborech v programu.

  • Obor názvů A název deklarovaný v oboru názvů mimo definici třídy nebo výčtu nebo bloku funkce je viditelný z bodu deklarace na konec oboru názvů. Obor názvů může být definován v několika blocích v různých souborech.

  • Název místního oboru A deklarovaný v rámci funkce nebo lambda, včetně názvů parametrů, má místní obor. Často se označují jako "místní". Jsou viditelné pouze z bodu deklarace na konec funkce nebo těla lambda. Místní obor je druh oboru bloku, který je popsán dále v tomto článku.

  • Obory tříd Názvy členů třídy mají obor třídy, který rozšiřuje v rámci definice třídy bez ohledu na bod deklarace. Přístupnost členů třídy je dále řízena publicpomocí , privatea protected klíčových slov. K veřejným nebo chráněným členům lze přistupovat pouze pomocí operátorů výběru členů (. nebo ->) nebo operátorů ukazatele na členy (.* nebo -).>*

  • Názvy oborů příkazů deklarované v příkazu for , if, whilenebo switch příkaz jsou viditelné až do konce bloku příkazu.

  • Rozsah funkce A obor funkce, což znamená, že je viditelný v těle funkce i před jeho bodem deklarace. Rozsah funkce umožňuje psát příkazy jako goto cleanup před cleanup deklarací popisku.

Skrytí názvů

Název lze skrýt jeho deklarací v uzavřeném bloku. Na následujícím obrázku je i deklarováno v rámci vnitřního bloku, a tím dojde ke skrytí proměnné přidružené k i v rozsahu vnějšího bloku.

Diagram znázorňující skrytí názvu oboru bloku
Blokování oboru a skrytí názvu

Výstup z programu zobrazeného na obrázku je:

i = 0
i = 7
j = 9
i = 0

Poznámka:

Argument szWhat je považován za argument nacházející se v oboru funkce. Proto je zpracováván stejně, jako by byl deklarován v nejvzdálenějším bloku funkce.

Skrytí názvů tříd

Názvy tříd lze skrýt deklarováním funkce, objektu, proměnné nebo enumerátoru ve stejném oboru. Název třídy je však stále přístupný, pokud je předpona klíčového slova class.

// hiding_class_names.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

// Declare class Account at global scope.
class Account
{
public:
    Account( double InitialBalance )
        { balance = InitialBalance; }
    double GetBalance()
        { return balance; }
private:
    double balance;
};

double Account = 15.37;            // Hides class name Account

int main()
{
    class Account Checking( Account ); // Qualifies Account as
                                       //  class name

    cout << "Opening account with a balance of: "
         << Checking.GetBalance() << "\n";
}
//Output: Opening account with a balance of: 15.37

Poznámka:

Jakékoli místo, pro které se volá název třídy (Account), musí být třída klíčového slova použita k odlišení od globální proměnné Account. Toto pravidlo neplatí, vyskytne-li se název třídy na levé straně operátoru rozlišení oboru (::). Názvy na levé straně operátoru rozlišení oboru jsou vždy považovány za názvy tříd.

Následující příklad ukazuje, jak deklarovat ukazatel na objekt typu Account pomocí klíčového class slova:

class Account *Checking = new class Account( Account );

Inicializátor Account (v závorkách) v předchozím příkazu má globální rozsah; je typu double.

Poznámka:

Opětovné použití názvů identifikátorů, jak je znázorněno v tomto příkladu, je považováno za špatný styl programování.

Informace o deklaraci a inicializaci objektů třídy naleznete v tématu Třídy, Struktury a Sjednocení. Informace o používání new operátorů a delete operátorů volného úložiště najdete v tématu nové a odstraňovací operátory.

Skrytí názvů s globálním oborem

Názvy s globálním oborem můžete skrýt explicitním deklarováním stejného názvu v oboru bloku. K názvům globálního oboru se ale dá přistupovat pomocí operátoru rozlišení oboru (::).

#include <iostream>

int i = 7;   // i has global scope, outside all blocks
using namespace std;

int main( int argc, char *argv[] ) {
   int i = 5;   // i has block scope, hides i at global scope
   cout << "Block-scoped i has the value: " << i << "\n";
   cout << "Global-scoped i has the value: " << ::i << "\n";
}
Block-scoped i has the value: 5
Global-scoped i has the value: 7

Viz také

Základní koncepty