Home CPP Module 02 : OCCF, 연산자 오버로딩
Post
Cancel

CPP Module 02 : OCCF, 연산자 오버로딩

Ex00

주요 개념

OCCF (Orthodox Canonical Class Form)

  • 다음 요소들을 모두 갖춘 클래스를 의미한다.
    • Default constructor (디폴트 생성자)
    • Copy constructor (복사 생성자)
    • Copy assignment operator (복사 대입 연산자 (오버로딩))
      • 레퍼런스를 리턴하는 이유?
        • chained assignment (a = b = c)를 위해
        • 위 코드의 해석 순서
          1. a에 b=c가 할당된다.
          2. b에 c가 할당된다.
        • 값으로 리턴한다면 1에서 b=c의 결과가 a에 할당될 수 없다.
          • 할당 결과가 임시 객체이기 때문
        • 참조자를 리턴한다면 할당의 결과가 lvalue이기 때문에 할당 chaining이 가능하다.
    • Destructor (소멸자)
  • 예시

    1
    2
    3
    4
    5
    6
    7
    
      class A
      {
        A();
        ~A();
        A(const A &a);
        A &operator= (const A &a);
      };
    

컴퓨터의 수 표현 방법

  • 정수의 표현
    • 컴퓨터는 0과 1을 사용해 2진수 형태로 정보를 저장한다. 정수는 해당 방법으로 정확하게 수를 표현할 수 있지만 실수는 이 방법을 사용할 수 없다.
  • 실수의 표현
    • 부동 소수점
      • 수를 소숫점을 이동시켜가며 다양한 형태로 표현할 수 있다.
      • IEE-754 부동소수점

        Untitled

        • 표현 방식 (S, M, E는 각각 부호부, 지수부, 가수부를 의미)
        \[N = (-1)^S * M * 2^{E-127}\]
        • 구성 (IEEE-754, 32bit)
          • 부호(sign) 비트 (1bit)
            • 숫자의 부호를 나타냄. 양수:0, 음수:1
          • 지수(exponent) 비트 (8bit)
            • 정규화를 거친 이후의 정수부
          • 가수(mantissa) 비트 (23bit)
            • 가수 또는 유효숫자를 나타냄
              • 가수 : 정규화를 거쳐 만들어진 소수부의 유효숫자
              • 유효숫자 : 수의 정확도에 영향을 주는 숫자
        • 문제
          • 오차 발생 가능
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          
            #include <stdio.h>
                          
            int main()
            {
                float   sum = 0;
                          
                for (int i=0; i<100; i++)
                    sum += 0.03;
            	printf("%f\n", sum);
            }
          
          • 위 코드를 실행시키면 예상되는 값인 3이 아닌 값이 출력되는 것을 알 수 있다.

          Untitled

  • 정수(integer) vs 부동 소수점 수(floating point number)
    • 정확도, 정밀도의 차이
      • 정확도(accuracy)
        • 크기가 실제 값과 얼마나 가까운지를 나타냄
      • 정밀도(precision)
        • 얼마나 많은 정보를 가질 수 있는지를 나타냄
       정수부동 소수점 수
      정확도높음낮음
      정밀도낮음높음
    • 일반적으로 사용하는 10진수를 컴퓨터에서 표현하려면 2진수로 변환해야 한다.
      • 문제점 : 오차 발생 가능
      • 해결책 : 근사값 저장
        • 고정 소수점
          • 개념 : 일정 크기의 비트를 부호 비트(x), 정수 비트(y), 소수 비트(z)로 나눈다.(x,y,z는 환경에 따라 다름)
          • 문제
            • 정수 비트 증가 : 정밀한 수의 표현이 불가
            • 소수 비트 증가 : 큰 수의 표현이 불가

static, const, static const 변수

  • static 변수
    • 클래스 당 하나씩만 생성
    • 클래스가 정의되기 전부터 메모리에 존재
    • 해당 클래스의 모든 객체가 공유하는 변수
  • const 변수
    • 값을 변경할 수 없는 변수
    • 값이 수정되지 않는다는 것을 보장해준다.
      • 변경된다면 컴파일 타임에 알 수 있음.
  • static const 변수
    • static 변수를 상수화시킨 변수
    • 모든 객체에서 공유하는 const 변수
  • 복사 생성자
    • 인자로 복사할 대상을 받는다.
    • 대상을 복사한 뒤에 객체를 생성한다.
  • 대입 연산자 오버로딩
    • 인자로 받은 객체를 복사해서 리턴한다.
  • Q&A
    • 복사 대입 연산자 오버로딩을 할 때 다음 조건의 필요성?
      • 조건 1.

        1
        2
        
          if (this != &f) // 이 부분
          		_fixed = f.getRawBits();
        
        • 같은 객체가 할당되는 비효율적인 작업을 방지한다.
      • 조건 2.

        1
        2
        
          if (this != &f)
              this->_fixed = f.getRawBits(); // this-> 부분
        
        • this : 현재 객체의 멤버라는 것을 명시적으로 알려준다.
        • 매개변수의 이름과 멤버 변수의 이름이 동일한 경우에 서로 구분하기 위해 사용된다.

Ex01

주요 개념

roundf 함수

  • 반올림된 값을 반환

fraction bit

  • 고정 소수점의 소수 비트를 의미
  • << (insertion)연산자 오버로딩
    • 클래스 외부에 선언 : 다른 클래스의 연산자를 오버로딩하는 것이기 때문.

고정 소수점을 만드는 방식

  • int
    • num « 8
    • 소수 비트만큼 쉬프트
  • float
    • num * 2^8 → 반올림
    • num에 직접 비트 쉬프트 하지 않고, 256을 곱하는 이유?
      • 실수형은 비트연산이 불가능하기 때문
    • roundf를 사용한 이유?
      • float을 고정 소수점으로 변환 시, 오차가 발생
        • 오차를 줄이기 위해 roundf로 반올림한다.

Ex02

주요 개념

연산자 오버로딩

  • 방법

    1
    
      operator오버로딩할연산자(매개변수목록)
    
  • 비교 연산자
    • bool 리턴
    • rawbits를 비교
  • 증감 연산자
    • 전위 연산
      • 참조를 리턴 : 변수의 값의 증감이 바로 반영되야 하기 때문
    • 후위 연산
      • 매개변수 int의 역할 : 전위 연산자와 구분하기 위한 dummy 매개변수
      • 원리
        • 미리 연산 전의 값을 복사 생성해서 임시 객체에 저장해둔다.
        • 기존 객체는 전위 증감 연산자로 값을 증가
        • 처음에 저장해둔 임시 객체를 리턴한다.
          • 후위 연산은 연산 결과가 바로 적용되지 않기 때문.
      • 후위 연산자 함수의 리턴타입이 const인 이유?
        • rvalue, lvalue 개념
        • 후위 연산자는 기존 값의 임시 복사본을 리턴한다. 이 값은 rvalue로 변경이 불가능해야 함. 따라서 const를 붙여줘서 리턴.

const 함수

  • const function(int a) 형태
    • 반환형이 const형이라는 의미
  • function(int a) const 형태
    • 함수가 해당 클래스의 멤버의 값을 변경하지 않는다는 의미

Q&A

  • 왜 위에 방식을 놔두고 아래 방식을 사용?
    • return (this->fixed_point_num > f.fixed_point_num);
    • return (fixed_point_num > f.getRawBits());
      • 둘 다 사용가능. getter를 쓰면 더 안전함.
  • 비교 연산자 오버로딩 할때 뒤에 const를 붙여줘야 하는이유?
    • 멤버 변수를 변경하지 않는다는 것을 보장하기 위해

Ex03

주요 개념

const_cast

  • 객체의 상수성(const) 를 없애는 형 변환
  • 사용 이유 : x,y 변수는 const인데 할당 대입 연산자로 변경하기 위해

삼각형 내부 점 판별 방법

  1. 확인하려는 임의의 점p와 삼각형의 각 선분들로 삼각형을 만들었을 때, 각 삼각형 넓이의 합=기존 삼각형의 넓이 라면 해당 점은 삼각형의 내부에 존재한다.
  2. 내부에 있다 = 삼각형의 각 선분을 기준으로, 남은 한 점과 항상 같은 위치에 존재한다.

삼각형의 넓이 공식

  • 신발끈 공식
    • 외적 응용
\[|(x_1*(y_2-y_3)+x_2*(y_3-y_1)+x_3*(y_1-y_2))|/2\]

구현 방법

  • bsp
    • 위 공식으로 구한 각 삼각형의 넓이와 기존 삼각형의 넓이를 비교
    • fixed 변수를 절대값으로 변경해주는 abs 함수 구현

평가 후기

  • static_cast 개념
  • 함수 선언할 때 const 함수로 선언해야 const Classname obj; 와 같이 생성된 객체가 해당 함수를 사용할 수 있다.
  • 임의의 점이 삼각형 위에 존재하면 false를 반환해야한다.

Ref.

This post is licensed under CC BY 4.0 by the author.

CPP Module 01 : 클래스

CPP Module 03 : 상속