언리얼 - C++ 32 : namespace, 입출력 구현 (cin, cout)

김정환·2025년 3월 24일

Unreal C++

목록 보기
32/37

1️⃣ namespace

범위 지정 연산자 ::

일반적으로 클래스의 경우, 클래스 내부에 선언한 기능에 접근하기 위해선
범위지정연산자::를 사용했음.

  • 일반적인 멤버 함수는 결국 객체(instance)가 필요하여 직접 호출은 못했음.
  • 다만, 정적 멤버함수 static 함수들은 위의 방식으로 접근 가능.
  • 객체없이 클래스로 바로 접근할 수 있음.
class CTest
{
public:
    static void MemberFunc()
    {
    }
};

int main()
{
    // 객체없이 호출가능
    CTest::MemberFunc();
    return 0;
}

namespace 개념

사용자 지정 이름 공간

namespace MYSPACE
{
	// 함수 밖에서 선언된 변수 == 전역 변수
	int g_int;
}

int main()
{
	g_int = 0; // 접근 불가
    
    // 네임스페이스 안에 있으므로 이렇게 접근해야함.
    MYSPACE::g_int = 0; // 가능
    
	return 0;
}

왜 쓰는가?

  • 사람이 대체로 생각이 비슷해서 변수명, 함수명을 직관적으로 명명하다보면 겹칠 수가 있음.
  • std namespace는 c++의 표준 입출력 함수, 기능들이 담겨있는 라이브러리임.
  • std를 만든 이유는 사용자가 std 내의 변수, 함수와 동일한 이름으로 선언할 수도 있기 때문임.
    • 표준으로 사용하는 기능들이기 때문에 이름이 겹칠 가능성이 높은 것.
    • 이 때문에 namespace로 묶어서 변수명, 함수명의 중복을 피한 것.

using 키워드

int main()
{	
	int aa = 0;
	std::cin >> aa;
    
    int output = Test(aa);
    
    std::cout << "aa is " << aa << endl;
    std::cout << "output : " << output << endl;

	return 0;
}
  • 근데 사용하다보면 namespace를 계속 명시하기 귀찮을 수 있음.
  • 이때 using 키워드를 이용해서 특정 namespace 사용을 명시하여
    위와 같은 반복적인 부분을 줄일 수 있음.
using namespace std;

int main()
{	
	int aa = 0;
	cin >> aa;
    
    int output = Test(aa);
    
    cout << "aa is " << aa << endl;
    cout << "output : " << output << endl;

	return 0;
}
  • 사실 그렇게 좋진 않은게, 본래 namespace의 목적을 상실함.
  • namespace 전체를 해제시키기 보다는 내부의 특정 기능만 해제할 수 있음.
    • 이렇게 특정 기능만 namespace를 해제해서 사용할 수도 있음
using std::cout;
using std::cin;
using std::endl;

int main()
{	
	int aa = 0;
	cin >> aa;
    
    int output = Test(aa);
    
    cout << "aa is " << aa << endl;
    cout << "output : " << output << endl;

	return 0;
}

2️⃣ c++ 입출력 : cin, cout

  • cout : ostream 객체의 extern 변수
  • cin : istream 객체의 extern 변수명
  • 즉, c++ 자체적으로 제공하는 istream, ostream 객체의 외부 변수
  • iostream.h 에 접근해서 사용하는 외부 변수.

입출력에서 <<, >>

  • 일반적인 비트연산자가 아니라 iostream 헤더에서 정의된 연산자 오버로딩이었음.

번외

빈 클래스의 크기는? : 아무것도 없으면 1 Byte를 줌

class CTest
{

}

CTest inst; // 

<<,>> 구현해보기

cout <<

class CMyOstream
{
public:
	CMyOstream& operator << (int _data)
    {
    	printf("%d", _data);
    	return *this;
    }
}
  • 이런 식으로 자기자신을 반환하여 연속적으로 <<, >>를 호출할 수 있도록 하는 것
  • wcout, wcin 2 Byte 단위로 문자열을 처리하는 객체도 있음.
class CMyOstream
{
public:
	CMyOstream& operator << (const wchar_t* _data)
    {
    	wprintf(L"%s", _data);
    	return *this;
    }
}

CMyOstream mycout;

int main()
{
	mycout << L"Hello" << endl;
    
    // 언어 설정, 한국어로 변경
    setlocale(LC_ALL, "korean");
    _wsetlocale(LC_ALL, "korean");
    
    mycout << L"안녕" << endl;
	return 0;
}

cin >>

class CMyIstream
{
public:
	CMyIstream& operator >> (wchar_t& _target)
    {
    	wscanf(L"%s", _target);
    	return *this;
    }
}

CMyIstream mycin;

int main()
{
	wchar_t wc;
	mycin >> wc;
    
	return 0;
}

endl

  • endl 은 함수임.
    • std 라이브러리 내에 있는 함수인 것.

void MyEndL()
{
	printf('\n');
}

class CMyOstream
{
public:
	CMyOstream& operator << (const wchar_t* _data)
    {
    	wprintf(L"%s", _data);
    	return *this;
    }
    
    CMyOstream& operator << (void(*func)(void))
    {
    	func();
    	return *this;
    }
}
  • 함수 포인터를 이용해서 << 뒤에 함수를 넘겨준 것임.

새로운 기능들이 아니라 오퍼레이터 오버로딩, 함수 포인터 등으로 구현해둔 것.

profile
만성피로 개발자

0개의 댓글