42서울 교육과정 4서클 CPP Module 01 학습 노트
42서울 본과정의 네 번째 서클에 포함된 프로젝트, “C++ Module 01”을 진행하며 작성한 메모입니다. 과제를 시작하기 전에 개념 학습을 위해 정리했습니다.
이번 모듈에서 익힐 개념
- Memory allocation
- References
- Pointers to members
- File streams
Memory allocation(메모리 할당)
컴퓨터의 메모리 공간은 크게 스택(stack), 힙(heap), 데이터(data), 코드(code), 네 부분으로 나뉜다.
- 스택: 지역변수, 매개변수 등이 할당. 임시 영역으로 함수 영역을 벗어나면 자동 소멸
- 힙: 동적으로 할당하는 메모리 공간. 프로그래머에 의해 할당/해제되며, 생성시 크기를 결정
- 데이터: 전역변수, 정적변수, 초기화한 배열 등이 할당. 프로그램 종료시까지 상주
- 코드: 프로그램의 명령어나 기계어 명령이 존재
이들은 특징에 따라 정적 메모리(static memory)와 동적 메모리(dynamic memory)로 나눌 수 있다.
- 정적 메모리: 전역(global) 변수, 정적(static) 변수, 지역변수, 매개변수 등을 저장
- 동적 메모리: 프로그램 실행 중 생성/소멸되는 변수를 저장. 힙 공간 사용
동적 메모리 할당 사용시 주의 사항
- 메모리 해제 후 포인터는 NULL로 꼭 초기화해 에러를 방지한다.
new
=>delete
,new[]
=>delete[]
로 쌍을 맞춰 사용한다.
Reference(참조)
C++에서 지원하는 변수 타입인 참조(Reference)는 다른 객체나 값의 별칭으로 사용되는 타입이다.
- 일반 변수(normal variable): 직접 값을 가짐
- 포인터 변수(pointer): 다른 값의 ‘주소’(또는 null)를 가짐
- 참조형 변수(reference): 다른 객체 또는 값의 ‘별칭’으로 쓰임
C++의 참조형의 종류는 non-const 값 참조형, const 값 참조형, r-value 참조형, 이렇게 세 가지가 있다.
- non-const 값 참조형: 앰퍼센드(
&
)를 이용해 선언 - const 값 참조형: const 키워드를 사용해 참조를 선언. 줄여서 const reference(상수 참조)라고 부름.
- r-value 참조형: C++11에서 추가됨. 따라서 “CPP Module 01”에서는 사용할 수 없음.
Pointers to members
멤버 포인터 변수는 특정 클래스(구조체 포함)에 속한 멤버만을 가리키는 포인터로, 아래처럼 선언한다.
RETURN_TYPE CLASSNAME::*VARNAME;
멤버 포인터 연산자는 .*
, ->*
형태로, 식의 왼쪽의 클래스에 대한 멤버 값을 반환한다.
이 포인터 연산자의 첫번째 피연산자와 두번째 피연산자는 각각 클래스와 멤버 포인터이다.
.*
의 첫번째 피연산자: 두번째 피연산자의 멤버 포인터의 클래스 타입이고, 해당 멤버 포인터에 접근이 가능해야 함. 또는 멤버 포인터의 클래스에서 명시적으로 파생된 클래스로, 해당 클래스에 엑세스할 수 있는 타입이어야 함->*
의 첫번째 피연산자: 두번째 피연산자의 “클래스 타입 포인터” 타입이거나 이로부터 명시적으로 파생된 클래스 타입이어야 함
만약 멤버 함수 포인터를 사용한다면 아래처럼 작성한다.
RETURN_TYPE (CLASSNAME::*MEMBER_VARNAME)(ARGS);
선언과 동시에 초기화시에는 아래처럼 작성한다.
RETURN_TYPE (CLASSNAME::*MEMBER_VARNAME)(ARGS) = &MEMBER_FUNCNAME;
File streams
C 언어에서는 파일 입출력을 위해서는 스트림을 형성한 후, 필요한 정보를 파일 구조체에 받아 포인터로 접근/사용한다. 이 과정에서 파일 관련한 데이터의 읽기/쓰기는 파일입출력 관련 함수를 활용한다(fputs, fputc, fgets 등등) 하지만 CPP에서는 스트림 관련 기능과 파일입출력 함수의 기능을 묶어서 클래스로 제공한다. FILE 구조체를 포인터로 사용하지 않고 객체에 정보를 저장한다. ([C++ 씨플플] 파일입출력 ifstream ofstream fstream 사용법. C언어와 C++ 파일입출력 차이. 파일읽고쓰는법 참고)
cout << "hello"; // 표준 출력
out << "hello"; // 파일 스트림 out에 등록된 파일에 출력
파일 스트림과 관련한 클래스
- ifstream: 파일 읽기
- ofstream: 파일 쓰기
- fstream: 읽기/쓰기 동시 가능
문자열 쓰기
put()
멤버 함수: 문자 출력<<
연산자:cout
에서처럼 사용할 수 있음
문자열 읽기
get()
멤버함수: 문자 입력getline()
멤버함수: 개행까지 받아옴
기타
CPP 클래스 생성자에서 멤버 변수를 초기화하는 방법
생성자 함수에서 초기화하는 방법과 초기화 리스트를 사용하는 방법이 있다.
// Class
#include <iostream>
class Foo {
public:
int bar;
Foo(int num): bar(num) {};
};
// 초기화 리스트
Foo(int num): bar(num) {};
// 함수에서 초기화
Foo(int num)
{
bar = num;
}
초기화 리스트를 써야만 하는 상황은 다음과 같다.(출처 - Hashcode - 생성자에서 콜론(:)은 왜 쓰는 건가요?)
- 클래스가 레퍼런스를 멤버로 가질 때
- non static const멤버가 있을 때
- default 생성자가 없을 때
- base class를 초기화할 때
- 생성자 파라미터의 이름이 데이터 멤버랑 같을 때(이 경우는 this를 써서 해결할 수도 있음)
Stdin 관련(cin
, getline()
)
cin
은 입력값의 기준을 스페이스, 엔터, 탭 등으로 나눔. 하지만 스페이스, 엔터, 탭 등의 문자가 먼저 나오면 그냥 무시하고 버퍼에는 그대로 남게 된다.getline()
은delim
을 지정하지 않는 한 개행(\n
)까지 받아들인다.
참고링크
CPP 참고링크
Memory allocation 참고링크
References 참고링크
- 소년코딩 - 참조형 변수 (Reference variable)(원문 - LearnCPP - 9.16 — Reference variables)
- 소년코딩 - C++ 07.16 - 참조와 const (Reference and const)(원문 - LearnCPP - 9.17 — References and const)