Scope - 범위

C++ 2019. 12. 25. 09:17
반응형

기본적으로 아주 자주 사용하는 {}에 대한 규칙과 명칭을 정확하게 이해하는 것이 중요하다. 또한 그래야만 전역이냐 혹은 변수냐에 따른 애매한 경우를 본인 스스로 해결할 수 있겠다 판단하였다.

-> 결론 애매한 부분을 확실히 잡아줌 ㅇㅇ

 

 

 

 

범위 (C++)

범위 (C++)Scope (C++) 이 문서의 내용 --> 클래스, 함수 또는 변수 같은 프로그램 요소를 선언 하면 해당 이름은 "표시" 고 프로그램의 특정 부분에 사용 되는 수 있습니다.When you declare a program element such as a class, function, or variable, its name can only be "seen" and used in certain parts of your program. 이름 표시

docs.microsoft.com

클래스, 함수 또는 변수 같은 프로그램 요소를 선언하면 해당 이름은 "표시가 된다"의 역할이고 프로그램의 특정 부분에 사용됩니다. 이름이 표시되는 컨텍스트를 해당 범위[Scope]라고 합니다. 예를 들어 함수 안에 x 변수를 선언할 시, x는 해당 함수 본문 내에서만 표시됩니다. 이것을 로컬 범위[local scope]라고 합니다. 서로 다른 범위에서는 단일 정의 규칙을 위반하지 않고 오류를 발생시키지 않습니다. 이런 식으로, 프로그램에서 같은 이름의 다른 변수를 가질 수 있습니다. 

 

자동 비정적 변수의 경우, 범위는 프로그램 메모리에서 생성 및 제거를 결정합니다.

범위는 다음과 같은 여섯 가지 종류가 있습니다.

  • 전역 범위 [Global scope]_ 전역 이름이 네임 스페이스는 클래스, 함수 또는 외부에서 선언됩니다. 그러나 C++ 에서는 이러한 이름조차도 암시적 전역 네임 스페이스가 존재합니다. 전역 이름의 범위를 선언 지점부터 선언된 파일의 끝까지 확장합니다. 전역 이름, 표시 유형 또한 링크의 규칙에 따라 적용됩니다. 링크는 프로그램에서 다른 파일의 이름을 표시되는지 여부를 결정합니다.

  • Namespace 범위 [Namespace scope]_ 모든 클래스 또는 열거형의 정의 또는 함수블록들의 외부 그리고 네임 스페이스 내에서 선언된 이름은, 선언 지점에서부터 네임 스페이스의 끝에서 표시됩니다. 다른 파일에서 여러 개의 블록에 네임 스페이스를 정의할 수 있습니다.

  • 지역 범위 [Local scope]_ 매개변수 이름을 포함한 함수 또는 람다의 내부에서 선언 된 이름은 지역 범위를 갖습니다. 이러한 범위를 "지역 [Local]" 이라고 합니다. 이 지역은 선언 시점부터 함수나 람다 본문의 끝에서 표시됩니다. 로컬 범위는 이 문서의 뒷부분에서 설명하는 블록 범위 종류입니다.

  • 클래스 범위 [Class scope]_ 클래스 멤버의 이름은 클래스 선언시점에 관계없이 정의 전체에서 확장 하는 클래스 범위를 갖습니다. 클래스 멤버 변수들의 액세스 가능여부는 public, private, protected 키워드로 관리할 수 있습니다. Public 또는 protected 멤버는 멤버 선택 연산자(. or ->)를 사용해서 혹은 포인터와 맴버 변수 관계에서는 (.* or ->*)으로만 액세스할 수 있습니다.

  • 구문 범위 [Statement scope]_ for, if, while 또는 switch 문 내에 선언된 이름은 그 구문이 끝날 때까지 표시됩니다.

  • 함수 범위 [Function scope]_ 레이블에는 함수 범위가 있습니다. 이는 레이블이 선언되기 전에 함수 본문 전체를 볼 수 있음을 뜻합니다. 함수 범위를 사용하면 cleanup 레이블을 선언하기 전에 goto cleanup 과 같은 명령문을 사용할 수 있습니다.

 

 

 

이름 숨기기

이름을 포함된 블록에서 선언하여 숨길 수 있습니다. 다음 그림에서는 i가 내부 블록 안에서 다시 선언되므로 바깥쪽 블록 범위에서 i와 연결된 변수가 숨겨집니다.

MSDN에서는 같은 이름이 선언될 경우 [숨긴다]고 표현한다.

 
블록 범위 및 이름 숨기기

그림에 표시된 프로그램의 출력은 다음과 같습니다.

1
2
3
4
= 0
= 7
= 9
= 0
 

 

+참고

szWhat 인수는 함수 범위에 있는 것으로 간주되므로 함수의 가장 바깥쪽 블록에서 선언된 것처럼 취급됩니다.

 

 

클래스 이름 숨기기

함수, 개체, 변수 또는 열거자를 동일한 코드에서 선언하여 클래스 이름을 숨길 수 있습니다. 그러나 클래스 이름에 액세스할 수 있습니다 때 키워드가 접두사로 붙는 클래스합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 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 balance of: "
         << Checking.GetBalance() << "\n";
}
//Output: Opening account with balance of: 15.37
 

 

6줄 주석_ 전역 영역에서 Account 클래스 선언

18줄 주석_ 클래스 Account 이름 숨기기(이름이 겹치지만 형이 다르기에 이전 클래스를 숨긴다.)

22줄 주석_ 클래스 이름과 같은 Account 이 쓰였다.
-> 하지만 Checking이란 이름의 class Account로 생성자를 시행해 그 인자에 일치하는 double형을 집어넣는 과정이다.

28줄 주석_ 실행 출력값은 15.37이다.

 

+참고

클래스 이름 위치 (Account)이 호출 되는 전역 범위 변수 Account와 구별 하기 위해 class 키워드를 사용해야 합니다. 이 규칙은 범위 결정 연산자(::)의 왼쪽에 클래스 이름이 나타나는 경우에는 적용되지 않습니다. 범위 결정 연산자의 왼쪽에 있는 이름은 항상 클래스 이름으로 간주됩니다.

다음 예제에서는 형식의 개체에 대한 포인터를 선언.하는 방법을 보여줍니다. 

 

Account를 사용하는 class 키워드:

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

Account 괄호 안 생성자 초기화 문에서는 double 형의 전역변수가 들어갑니다.

 

+참고

이 예제와 같이 식별자 이름을 다시 사용하는 것은 좋지 않은 프로그래밍 스타일로 간주됩니다. -> 헷갈리니깡

 

 

클래스 개체의 선언 및 초기화에 대한 정보를 더 알아보고 싶다면 클래스, 구조체 및 공용 구조체을 참조하세요. new delete의 오퍼레이터를 다루는 정보는 new and delete operators을 참조하세요.loca

 

 

 

전역 범위에서 이름 숨기기

블록범위(함수나 클래스 즉, 전역이 아닌 범위)에서 전역범위 변수와 이름이 같은 변수를 명시적으로 선언하여 이름을 숨길 수 있습니다. 그리고, 전역범위 이름은 결정 연산자(::)를 사용해 엑세스 할 수 있습니다.

 

예제_

1
2
3
4
5
6
7
8
9
10
#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";
}
 
 

 

Output

1
2
Block-scoped i has the value: 5
Global-scoped i has the value: 7
 

눈여겨 볼점은 예제에서 9번줄 [::i] 문이다. 해당 연산은 전역범위에 잇는 3번줄 int i = 7;의 i를 나타낸다(엑세스한다.).

반응형
Posted by Kestone Black Box
,