42서울 교육과정 4서클 CPP Module 01 학습 노트

29 Mar 2021

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 참조형, 이렇게 세 가지가 있다.

  1. non-const 값 참조형: 앰퍼센드(&)를 이용해 선언
  2. const 값 참조형: const 키워드를 사용해 참조를 선언. 줄여서 const reference(상수 참조)라고 부름.
  3. 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 참고링크

Pointers to members 참고링크

File streams 참고링크

TAGS: 42seoul forty-two 42cursus cpp