[C++] namespace, cin/cout

꿈별·2023년 6월 4일
0

C++

목록 보기
22/27
  • 클래스 내부에 선언한 기능에 접근하려면 범위 지정 연산자(::)를 사용한다.
    -> 비슷한 개념인 namespace

✔namespace

말 그대로 이름 공간.

  • 네임스페이스를 생성하고 전역변수를 만든 뒤, 메인에서 전역변수를 정의하려고 하면 오류가 뜬다.

-> main 밖에서 선언되었으니 전역변수는 맞지만, 네임스페이스 안에 만들어진 것이므로 그 바깥에서 사용하려면 범위 지정 연산자(::) 를 사용해야 한다.

-> 입출력할 때도 똑같은 방식으로 코드를 작성한다.

  • namespace를 사용하는 이유
    • 네임스페이스 std 에는 C++ 표준 라이브러리의 모든기능들이 들어 있다.
      -> 표준 라이브러리를 사용하는 사용자가 동일한 이름의 변수를 만들면 구분이 안 되기 때문 (변수명 중복 방지)
      -> 네임스페이스가 다르면 동일한 변수명도 사용할 수 있다.

using 키워드

매번 네임스페이스 이름과 범위 지정 연산자를 작성하기 번거로울 때 사용하는 키워드

  • 아래와 같이 std라는 네임스페이스를 사용하겠다고 선언하면, 해당 네임스페이스가 존재하지 않는 것으로 취급되어(해제됨), 내부 기능들을 바로 사용할 수 있다.

using namespace std;
cout << "출력" << 123 << endl;

❗ 하지만 결과적으로 네임스페이스를 사용하는 목적을 상실해 버린다.

-> 어느 공간의 변수인지 구분할 수 없어 모호해진다.

💡 따라서 namespace 내부의 일부 기능만 해제해서 사용하도록 한다.

//using namespace std;
using std::cout;
using std::endl;

int main()
{
	cout << "출력" << 123 << endl;
}

cout / cin

  • coutcin은 각각 ostream/istream이라는 클래스의 객체 이름이다.

-> 전역 변수인 객체를 생성해 둔 것인데, extern 키워드가 있으므로 모든 파일에서 접근할 수 있다.

<< / >>

: 연산자 오버로딩된 것이다.

  • cout
    : 표준 출력 스트림을 처리하는 객체

<< 연산자 오버로딩 예시

class CMyOStream
{
public:
	CMyOStream& operator << (int _idata)
	{
    	printf("%d", _idata);
		return *this;
	}
};

CMyOStream mycout;

int main()
{
	mycout << 10;
}
  • cout << "출력" << 123 << endl;
    -> 순차적으로 연산을 마칠 때마다 자기 자신을 반환한다.
    (cout << "출력" 을 마치면 다시 cout << 123, 그 다음엔 cout << endl)
    -> 그러려면 연산자 함수는 반환 타입이 자기 자신의 참조 값이어야 한다.
    (CMyOStream& operator << (int _idata))

  • wcout
    : 문자열을 2바이트 단위로 취급한다.

<< 연산자 오버로딩 예시2

CMyOStream& operator << (const wchar_t* _pString)
{
	wprintf(L"%s", _pString);
	return *this;
}
//한글 깨짐 때문에 추가해줘야 함
setlocale(LC_ALL, "korean");
_wsetlocale(LC_ALL, L"korean");
    
mycout << 123;
mycout << L"한글";

  • cin
    : 표준 입력 스트림을 처리하는 객체
    -> C에서는 변수의 주소를 받아와서 입력했었는데,
    C++은 참조 변수를 사용하여 입력받는다.
    (굳이 주소를 넘기지 않아도, 변수를 참조하면 됨)

>> 연산자 오버로딩 예시

CMyOStream& operator >> (int& _idata)
{
	scanf_s("%d", &_idata);
	return *this;
}
int a = 0;
mycout >> a;

-> 원본을 수정해야 하므로 const 키워드 붙이지 않음

  • cout의 endl 함수까지 구현해보기
void MyEndl()
{
	wprintf(L"\n");
}
CMyOStream& operator << (void(*_pFunc)(void))
{
	_pFunc(); 
	return *this;
}
mycout << MyEndl;

-> (반환타입은 void, 인자가 없는(인자도 void)) 함수의 주소를 받아와서 호출해 준다.


[참고]
https://youtu.be/kAsnMlsB_Ks

0개의 댓글