CPP/씹어먹는 c++

[c++개념공부]참조자와 이름공간

뜨거운 개발자 2023. 1. 27. 19:25


💻

이름공간(namespace)

  • std란 : c++의 표준라이브러리의 모든 함수, 객체들이 정의되어 있는 이름공간(namespace)이다.
  • 이름공간의 존재이유 : 같은 이름의 함수들을 사용하기 위해서! (모듈화 프로그래밍을 더 편리하게 하기 위해서 이다.)코드가 길어질수록 중복된 이름을 가진 함수들이 많아진다. C++ 에서는 이를 구분하기 위해, 같은 이름이라도, 소속된 이름 공간이 다르면 다른 것으로 취급한다. 즉 C++에서는 같은이름의 함수를 이름공간만 다르게해서 사용이 가능한 것이다.
    • 예시모음
      • 이름공간 정의 예시
        //header.h 내부 예시  namespace header1 { int foo(); // 사용할 아무 함수나 적어놓는다. void bar(); } //다음과 같이 정의한  header.h 를 #include<header.h> 를 하게 되면 사용이 가능하다.
      • 이름공간 내부에서의 호출 예시
        • 이름공간 내부에서 사용하는 함수는 지정해주지 않아도 그 이름공간의 함수를 사용한다!
        #include "header1.h" #include "header2.h"  namespace header1 { int func() {   foo();           // 알아서 header1::foo() 가 실행된다.   header2::foo();  // header2::foo() 가 실행된다. } }  // namespace header1

         

      • 일반적인 호출 예시
        #include "header1.h" #include "header2.h" using namespace header1;  int main() {   header2::foo();  // header2 에 있는 함수를 호출   foo();           // header1 에 있는 함수를 호출 }// 복습중 알게된 사실 : using namespace를 하고 메인문 위에 함수를 하나 만들면 컴파일러는 우선순위를 정하지 못해서 오류가 발생한다.
      • 주의사항(using namespace std;)

        using namespace std; 와 같이 어떤 이름공간을 사용하겠다고 하는 것은 권장되지는 않는다.

        왜냐하면 std 에 이름이 겹치는 함수를 만들게 된다면, 오류가 발생하기 때문이지요.

        게다가 C++ 표준 라이브러리는 매우 매우 거대하므로, 정말 수 많은 함수들이 존재하고 있습니다.

        std 에는 매번 수 많은 함수들이 새롭게 추가되고 있기 때문에 C++ 버전이 바뀔 때 마다 기존에 잘 작동하던 코드가 이름 충돌로 인해 동작하지 않게되는 문제가 발생할 수 있습니다.

        따라서 권장하는 방식은 using namespace std; 같은 것은 사용하지 않고, std:: 를 직접 앞에 붙여서 std 의 이름공간의 함수이다 라고 명시해주는 것이 좋습니다. 또한, 여러분이 작성하는 코드는 여러분 만의 이름 공간에 넣어서 혹시 모를 이름 충돌로 부터 보호하는 것이 중요합니다.

       

  • 이름없는 이름공간(static 과 유사)
    #include <iostream> namespace 
    { 
        // 이 함수는 이 파일 안에서만 사용할 수 있습니다. 
        // 이는 마치 static int OnlyInThisFile() 과 동일합니다.
        int OnlyInThisFile() {}  
        // 이 변수 역시 static int x 와 동일합니다. 유사하지만 완전히 같은건 아니다. 
        int only_in_this_file = 0;
    } 
    // namespace 
    int main() 
    {  
        OnlyInThisFile();   
        only_in_this_file = 3; 
     }

 

 

참조자(레퍼런스 - reference)

특징

  • 레퍼런스는 포인터와 상당히 유사하다.
  • 레퍼런스는 반드시 처음에 누구의 별명이 될 것인지 지정해야 합니다.
  • 레퍼런스가 한 번 별명이 되면 절대로 다른 이의 별명이 될 수 없다.
  • 레퍼런스는 메모리 상에 존재하지 않을 수 도 있다. -컴파일 할때 레퍼런스가 쓰인 모든곳을 바꿔주면 되기 때문이다.
  • 존재하는 경우는 함수 인자로 레퍼런스를 받을 때 주소를 전달하기 위해서 메모리가 사용된다.
  • 함수 인자로 레퍼런스 받기
    int change_val(int &p)
    {   p = 3;    return 0; }
    // p가 정의되는 순간이 함수를 호출하는 순간이므로 이는 사용이 가능하다.
  • 금지된 친구들
    • 참조자의 참조자(int &&c =a)는 c++에서 금지하고 있다.
    • 상수에 대한 참조자 - 일반적으로는 금지되어 있지만
      • int &ref = 4; 이건 금지
      • const int &ref = 4; 이렇게 하면 사용이 가능하다.
    • 레퍼런스 배열과 포인터는 존재할 수 없다.( 주소값이 존재하지 않기 떄문.)
    • 배열들의 레퍼런스
      int arr[3] = {1, 2, 3};   
      int(&ref)[3] = arr; 
      //배열들의 레퍼런스의 경우 반드시 크기를 명시해주어야만 한다.

 

레퍼런스를 리턴하는 함수

  • 지역변수 레퍼런스를 리턴하는 함수는 댕글링 레퍼런스가 생겨서 안된다.
    • 댕글링 레퍼런스란: 원래 참조하던 변수가 사라진 레퍼런스를 댕글링 레퍼런스라고 한다.
    • 되는 경우가 있을수도 있는데 undifined behavior 이라서 언제 터질지 모른다.
  • 지역변수의 리턴값을 레퍼런스로 받는건 상수값을 레퍼런스로 받는 것과 같다
    • const int &ref = func(); 는 가능

 


Uploaded by

N2T
728x90