Orthodox 규정을 따르면서 개발할 것
(아래 네 가지 형태를 명시적으로 정의하여 선언할 것)
1. 기본 생성자
2. 복사 생성자
3. 복사 대입 연산자
4. 소멸자
class A
{
A();
~A();
A(const A &a);
A &operator=(const A &a);
};
같은 클래스 타입의 객체에 대한 참조를 인자로 전달받아, 그 참조를 가지고 자신을 초기화하는 방법
A::A(const A &a) {
*this = a; // 오버로딩된 할당 연산자 호출
}
A origin; // 기본 생성자 호출
A copied(origin); // 복사 생성자 호출
대입(할당) 연산자 오버로딩
기존 대입 연산자(=)를 재정의
operator 키워드와 연산자(=)를 묶어서 함수의 이름을 정의A &A::operator=(const A &a) {
// 값 복사 실행
return (*this);
}
A a1; // 기본 생성자 호출
A a2 = a1; // 복사 생성자 호출
A a3; // 기본 생성자 호출
a3 = a2; // 복사 대입 연산자 사용
깊은 복사를 하는 이유
- 생성자 내에서 동적 할당을 하는 경우, 객체 소멸 과정에서 중복으로 delete를 하게 됨
- 원래 가리키던 메모리의 포인터를 삭제하지 않고 잃어버리게 되어 메모리 누수 발생
고정 소수점, 부동 소수점 등 구현은 뒤에서 하기 때문에 여기서는 클래스를 OCF에 맞춰서 생성하기만 하면 됨
Fixed 클래스integer 멤버 변수: 고정 소수점 숫자static constant integer 멤버 변수: 소수부를 표현할 비트 수. 항상 8int getRawBits( void ) const;: 고정 소수점 값의 raw 값 리턴void setRawBits( int const raw );: 고정 소수점 수의 raw 값 설정int main(void) {
Fixed a;
Fixed b(a);
Fixed c;
c = b;
std::cout << a.getRawBits() << std::endl;
std::cout << b.getRawBits() << std::endl;
std::cout << c.getRawBits() << std::endl;
return (0);
}
$> ./a.out
Default constructor called
Copy constructor called
Copy assignment operator called
getRawBits member function called
Default constructor called
Copy assignment operator called
getRawBits member function called
getRawBits member function called
0
getRawBits member function called
0
getRawBits member function called
0
Destructor called
Destructor called
Destructor called
$>
소수부를 표현할 비트가 고정되어 있는 방식
2진수 변환 후 정수부에 1만 남을 때까지 소수점을 왼쪽으로 이동시키는 정규화 과정을 거치는 방식
1.xxx... * 2^nn)에 bias를 더한 값을 지수부에 저장 (지수의 부호를 표현하기 위해 필요)2^(8 - 1) - 1 = 127xxx...)는 가수부(23비트)에 그대로 저장 (정규화 후 1.11101 * 2^2)면 가수부는 11101)<cmath>의 roundf()
인자로 주어진 수를 반올림하여 리턴
float roundf (float x);
Fixed 클래스const int를 인자로 받는 생성자: 인자로 받은 수를 고정 소수점 값으로 변환const float를 인자로 받는 생성자: 인자로 받은 수를 고정 소수점 값으로 변환float toFloat( void ) const;: 고정 소수점 값을 부동 소수점 값으로 변환int toInt( void ) const;: 고정 소수점 값을 정수로 변환<<)를 고정 소수점 값의 부동 소수점 표현을 매개 변수로 전달된 출력 스트림에 삽입toFloat() 호출서브젝트의 고정 소수점의 소수부 표현 비트는 8비트
👉 32 비트 체계에서 앞의 24비트를 정수로, 뒤의 8비트를 소수로 표현
<< 연산으로 8비트의 빈 공간을 만듦n << 8<< 같은 쉬프트 연산자를 사용할 수 없음int이므로 (남은 소수부를 없애고 + 좀더 정확한 연산을 위해) 허용 함수인 roundf를 사용하여 반올림roundf(n * (1 << 8))int)을 float으로 변환한 뒤 << 연산한 값을 다시 되돌림static_cast<float>(n) / (1 << 8)int main(void) {
Fixed a;
Fixed const b(10);
Fixed const c(42.42f);
Fixed const d(b);
a = Fixed(1234.4321f);
std::cout << "a is " << a << std::endl;
std::cout << "b is " << b << std::endl;
std::cout << "c is " << c << std::endl;
std::cout << "d is " << d << std::endl;
std::cout << "a is " << a.toInt() << " as integer" << std::endl;
std::cout << "b is " << b.toInt() << " as integer" << std::endl;
std::cout << "c is " << c.toInt() << " as integer" << std::endl;
std::cout << "d is " << d.toInt() << " as integer" << std::endl;
return (0);
}
$> ./a.out
Default constructor called
Int constructor called
Float constructor called
Copy constructor called
Copy assignment operator called
Float constructor called
Copy assignment operator called
Destructor called
a is 1234.43
b is 10
c is 42.4219
d is 10
a is 1234 as integer
b is 10 as integer
c is 42 as integer
d is 10 as integer
Destructor called
Destructor called
Destructor called
Destructor called
$>
멤버 함수로 구현
> < >= <= == !=+ - * /전/후위 ++, 전/후위 --비교 연산자 오버로딩 활용
min(): 2개의 고정 소수점 수에 대한 참조를 받아서 작은 것 리턴min(): 2개의 const 고정 소수점 수에 대한 참조를 받아서 작은 것 리턴max(): 2개의 고정 소수점 수에 대한 참조를 받아서 큰 것 리턴max(): 2개의 const 고정 소수점 수에 대한 참조를 받아서 큰 것 리턴int main(void) {
Fixed a;
Fixed const b(Fixed(5.05f) * Fixed(2));
std::cout << a << std::endl;
std::cout << ++a << std::endl;
std::cout << a << std::endl;
std::cout << a++ << std::endl;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << Fixed::max(a, b) << std::endl;
return (0);
}
$> ./a.out
0
0.00390625
0.00390625
0.00390625
0.0078125
10.1016
10.1016
$>
이진 공간 분할법
👉 서브젝트에서는 점이 삼각형 안에 있는지만 판단하면 되기 때문에 굳이 트리까지 생성할 필요는 없을 듯
주어진 점이 삼각형 안에 있는지 아닌지 판단하기
Point 클래스Fixed const xFixed const yx, y를 0으로 초기화const float을 받아서 x, y를 초기화하는 생성자복사 대입 연산자를 오버로딩할 때 const 값을 리턴하지 않아 발생하는 오류
Fixed클래스에서=연산자를 오버로딩할 때Fixed &형을 반환하기 때문에,Point의 복사 대입 연산자를 오버로딩하면서_x = point.getX();와 같이 사용할 수 없음
👉const_cast<T>로const를 일시적으로 제거
bool bsp( Point const a, Point const b, Point const c, Point const point);
a, b, c: 삼각형의 꼭짓점point: 확인할 점true: 점이 삼각형 안에 있는 경우false: 그렇지 않은 경우 (삼각형의 꼭짓점이나 변에 있는 경우 포함)