[필기테스트 대비] 내가 보기 위한 C++ 정리 1 (Const, Reference, Constructor, Overloading)

2024. 12. 2. 18:29Other/C++

Class / Instance

  • Class : 객체에 대한 설계도
  • Instance : 설계도를 기반으로 만들어진 객체

Constant

Const non-member variable

  • int const a
  • const int a
    → 동일한 의미

Const member variable

  • const int * num → 포인터가 가리키는 값을 상수화
  • int * const num → 포인터 변수 자체를 상수화
  • const int * const * a const → a,_a,*_a를 모두 상수화

동적 할당 / 정적 할당

  • 코드 영역
    • 실행될 프로그램의 코드가 저장되는 영역
  • 데이터 영역
    • 전역 변수와 정적 변수가 할당되는 영역
    • 시작과 동시에 할당되고, 프로그램이 종료되어야 소멸되는 영역
  • 스택 영역
    • 함수 호출시 생성되는 지역 변수와 매개 변수가 저장
    • 함수 호출이 완료되면 소멸
    • 컴파일 타임에 크기가 결정됨
  • 힙 영역
    • 프로그래머가 직접 메모리를 할당 / 해제하는 공간
    • FIFO 방식으로 관리됨
    • 런타임에 크기가 결정됨

이름과 달리, 스택과 힙 영역이 반드시 스택이나 힙 자료구조를 사용하는 것은 아님

C++ 차원에서의 동적 할당 / 해제

  • T t = new T / T * ptrT = new T[n]
  • delete t / delete [] ptrT
  • 클래스를 인스턴스로 생성하기 위해 new를 사용할 경우, 자동으로 Default 생성자가 불리게 됨

Reference

  • 변수에 대한 다른 이름을 붙히는 것
  • 한번 만든 참조자의 대상 변경은 불가능
    • 다른 대상을 가리켜야 할 경우, 포인터를 사용해야 함.
    • ranged-for에서 참조자를 사용할 때, 대상이 바뀌는 것은 사실 새로운 참조자를 매번 생성하는 것임.

Non-const reference

  • 임시 객체(r-value)와 상수 객체(const l-value)에 대한 참조만 가능

Const reference

  • 임시 변수를 통해 Const인 변수 또한 참조 가능
  • 값의 변경 불가능

Reference function

  • 함수에서 참조자 리턴을 통해, 받은 인자와 동일한 참조 리턴 가능
  • 참조자를 리턴하는 함수에서 로컬 변수나 함수 내 임시 객체 등을 리턴하지 않도록 주의 필요 (Dangling Reference의 가능성)

L-value / R-value

  • l-value : 메모리 주소를 갖고 식의 왼쪽에 올 수 있는 값
    • 수정 가능/불가능과는 무관
  • r-value : 일시적이고 메모리 주소를 갖지 않을 수 있는 값
    • const reference로만 참조 가능
  • pr-value (pure r-value) : 계산된 결과로, 값만 존재하는 일시적인 데이터
  • x-value (expiring value) : 자원을 소유하지만, 곧 이동되거나 소멸될
  • gl-value (generalized l-value) : 메모리 주소를 갖고 일반화된 값
  • gl-value ⊇ (l-value ∪ x-value) : have memory?
  • r-value ⊇ (pr-value ∪ x-value) : is temporary?

오버로딩

  • 인자에 따라 구분 가능한 같은 이름의 새로운 함수를 정의

오버로딩 과정

  1. 타입이 정확하게 일치하는 함수 정의 탐색
  2. 형변환을 통해 호출 가능한 함수 정의 탐색
    1. char, unsigned char, short → int
    2. unsigned short → int, unsigned int
    3. float → double
    4. enum → int
  3. 좀 더 포괄적인 형변환 시도
    1. 임의의 numeric과 enum을 다른 numeric 타입으로 변환
    2. 0을 포인터 형식이나 값 형식으로 변경
  4. 사용자 정의 형변환 시도 (operator int()…)

같은 단계에서 두개 이상의 후보 발생시 ambigous 오류 발생

생성자 및 소멸자

  • 객체가 생성되고 소멸될 때 자동으로 불리는 함수
    • T(arg…), ~T()
  • 오버로딩 가능

Default 생성자

  • 인자를 갖지 않는 생성자
  • 명시적으로 컴파일러에서 만든 Default 생성자 사용
    • T() = default

소멸자

  • 생성자에서 명시적으로 할당받은 메모리를 해제해야 함
  • Scope 내에서의 정적 변수의 활용이 끝날 때에도 자동으로 불림

복사 생성자

  • T(const T & t)
  • 생성시기에 T a = b와 같이 대입을 할 경우에도 T a(b)로 간주하여 자동으로 복사 생성자를 호출 함
    • 단, 이미 생성된 객체에 a = b와 같이 대입을 할 경우 대입 연산자가 호출됨
  • 객체를 함수에 값의 형태로 전달할 때에도 복사 생성자가 호출됨
  • 컴파일러에서 자동으로 생성한 복사 생성자를 사용할 경우, 포인터의 할당과 해제에 주의 해야함.
    • 얕은 복사로 인한 이중 해제의 위험이 있음
    • 동적으로 할당해야하는 멤버 변수가 있는 등 깊은 복사를 구현해야할 경우, 직접 복사 생성자를 구현해야 함

Initializer List

  • T(int x, int y): x(x), y(y){}
  • Initializer List를 사용하지 않고 클래스 형식의 멤버 변수에 대입을 할 경우, 복사 생성자가 불리는 오버헤드가 발생함

Static 멤버 변수

  • 클래스의 모든 객체가 공유하는 변수
  • 인스턴스와 독립적으로 존재하여, 클래스가 메모리에 로드될 때 한번만 할당됨
  • static int t; T::t = 1;

Static 멤버 함수

  • 클래스의 객체와 독립적인 함수
  • 정적 멤버 변수에만 접근 가능
  • static void SomeFunction(); T::SomeFunction();

This 포인터

  • 현재 객체의 주소를 가리키는 특수한 포인터 (const T* this)
    • 멤버 함수 내에서만 유효함
  • *this를 함수 리턴값을 통해 받고자 한다면, T& 형태로 값을 리턴해야 함

Const 멤버 함수

  • int f() const;
  • 해당 객체의 상태를 변경하지 않음을 보장하는 함수

연산자 오버로딩

  • 클래스의 기본 연산자를 직접 정의하는 것
  • ex) bool operator==(T& t)

종류

  • bool operator==(T& t);
  • T operator (+,*,-,/) (const T& t) const;
  • T operator = (const T& t)
    • 따로 정의하지 않더라도 자동으로 디폴트 대입 연산자가생성됨
  • T operator (+=,*=,-=,/=) (const T& t);

Friend

  • private으로 정의된 멤버 변수나 함수를 다른 클래스나 함수에서 사용할 수 있도록 하는 것
  • ex) friend void SomeClass::SomeMethod();
  • T operator (T& a, T& b)를 Friend하여 효과적으로 연산자 오버로딩 가능

Stream Operator

  • ostream& operator<<(ostream& os, const T& t);
  • istream& operator>>(istream& is, const T& t);

Index Operator

  • T& operator[](const int index);

Cast operator

  • operator T2(){return data;}

Increment/Decrement operator

  • operator++(); //++x
  • operator--(); //--x
  • operator++(int); //x++
  • operator--(int); //x--
  • 후위 증감 연산자의 경우, 복사 연산자의 호출이 필요하므로 느림.