CPP Module 02
- CPP02부터는 Orthodox Canonical Form 을 준수하여 작성해야함
- Orthodox Canonical Form은 기본 생성자, 기본 소멸자, 복사 생성자, 할당 연산자 오버로딩을 명시적으로 선언해놓은 형식을 말함
- 이를 통해 클래스에 포인터나 참조 형식이 있을 때, 깊은복사 와 얕은복사를 비롯한 여러가지 잠재적인 버그를 해결하는데에 도움을 줄 수 있음
- Cpp Module 02에서는 클래스의 생성자와 소멸자를 Orthodox Canonical Form으로 정의하고 여러 연산자들을 Overloading하는것을 실습할 수 있음
class A
{
A();
~A();
A(const A &a);
A &operator= (const A &a);
};
ex00
- 고정소수점을 표현할 수 있는 Class를 만들어보는 과제
- Private멤버
고정소수점 값을 저장할 정수형 변수
분수 비트의 수를 저장하는 정적 정수형 상수. 이 상수는 항상 8의 값을 가짐
- Public멤버
고정 소수점 값을 0으로 초기화해 줄 기본 생성자, 기본 소멸자, 복사생성자, 할당 연산자 오버로딩
고정 소수점 값 원본을 반환하는 멤버 함수 int getRawBits( void ) const
고정 소수점 값 원본을 설정하는 멤버 함수 void setRawBits( int const raw )
class Fixed
{
private:
int fixed_int;
static const int fraction_bit = 8;
public:
Fixed();
Fixed(const Fixed &fix);
Fixed &operator=(const Fixed &fix);
int getRawBits( void ) const;
void setRawBits( int const raw );
~Fixed();
};
Fixed::Fixed()
{
std::cout << "Default constructor called" << std::endl;
this->fixed_int = 0;
}
Fixed::Fixed(const Fixed &fix)
{
std::cout << "Copy constructor called" << std::endl;
*this = fix;
}
Fixed &Fixed::operator=(const Fixed &fix)
{
std::cout << "Copy assignment operator called" << std::endl;
if (this != &fix)
{
this->fixed_int = fix.getRawBits();
}
return (*this);
}
void Fixed::setRawBits( int const raw )
{
this->fixed_int = raw;
}
int Fixed::getRawBits( void ) const
{
std::cout << "getRawBits member function called" << std::endl;
return(this->fixed_int);
}
Fixed::~Fixed()
{
std::cout << "Destructor called" << std::endl;
}
ex01
- ex00에서는 0.0만을 사용할 수 있었기때문에 더욱 보강해야함
- 추가 Public멤버
매개 변수로 정수형 상수를 받아와 이를 대응되는 고정 (8) 소수점 값으로 변환하는 생성자
매개 변수로 부동 소수점 상수를 받아와 이를 대응되는 고정 (8) 소수점 값으로 변환하는 생성자
고정 소수점 값을 부동 소수점 값으로 변환하는 멤버 함수 float toFloat( void ) const
고정 소수점 값을 정수 값으로 변환하는 멤버 함수 int toInt( void ) const;
매개변수의 출력 스트림에 고정 소수점 값의 부동 소수점 표현을 삽입하는 « 연산자 오버로딩
Fixed::Fixed(const int num)
{
std::cout << "Int constructor called" << std::endl;
this->fixed_int = num << this->fraction_bit;
}
Fixed::Fixed(const float num)
{
std::cout << "Float constructor called" << std::endl;
this->fixed_int = roundf(num * 256);
}
int Fixed::toInt( void ) const
{
return (this->fixed_int >> this->fraction_bit);
}
float Fixed::toFloat( void ) const
{
return((float)this->fixed_int / (256));
}
std::ostream &operator<<(std::ostream &out, const Fixed &fix)
{
out << fix.toFloat();
return (out);
}
ex02
- 여러가지 연산자 오버로딩을 추가해보기
여섯 개의 비교 연산자: >, <, >=, <=, ==, !=
네 개의 산술 연산자: +, -, *, /
고정 소수점 값을 1 + ε > 1와 같은 가장 작은 표현법 ε로부터 증가 또는 감소시키는 전위 증가 연산자, 후위 증가 연산자, 전위 감소 연산자, 후위 감소 연산자
두 개의 고정 소수점 값 참조를 받아 가장 작은 값의 참조를 반환하는 정적 멤버 함수 min
두 개의 고정 소수점 상수 값의 참조를 받아 가장 작은 상수 값의 참조를 반환하는 오버로딩
두 개의 고정 소수점 값 참조를 받아 가장 큰 값의 참조를 반환하는 정적 멤버 함수 max
두 개의 고정 소수점 상수 값의 참조를 받아 가장 큰 상수 값의 참조를 반환하는 오버로딩
class Fixed
{
private:
int fixed_int;
static const int fraction_bit = 8;
public:
Fixed();
Fixed(const int num);
Fixed(const float num);
Fixed(const Fixed &fix);
int getRawBits( void ) const;
void setRawBits( int const raw );
float toFloat( void ) const;
int toInt( void ) const;
bool operator>(const Fixed &fix) const;
bool operator<(const Fixed &fix) const;
bool operator>=(const Fixed &fix) const;
bool operator<=(const Fixed &fix) const;
bool operator==(const Fixed &fix) const;
bool operator!=(const Fixed &fix) const;
Fixed& operator=(const Fixed &fix);
Fixed operator+(const Fixed &fix) const;
Fixed operator-(const Fixed &fix) const;
Fixed operator/(const Fixed &fix) const;
Fixed operator*(const Fixed &fix) const;
Fixed& operator++(void);
Fixed& operator--(void);
const Fixed operator++(int);
const Fixed operator--(int);
static Fixed &min(Fixed &fix1, Fixed &fix2);
static const Fixed &min(const Fixed &fix1, const Fixed &fix2);
static Fixed &max(Fixed &fix1, Fixed &fix2);
static const Fixed &max(const Fixed &fix1, const Fixed &fix2);
~Fixed();
};
bool Fixed::operator>(const Fixed &fix) const
{
return (this->getRawBits() > fix.getRawBits());
}
bool Fixed::operator<(const Fixed &fix) const
{
return (this->getRawBits() < fix.getRawBits());
}
bool Fixed::operator>=(const Fixed &fix) const
{
return (this->getRawBits() >= fix.getRawBits());
}
bool Fixed::operator<=(const Fixed &fix) const
{
return (this->getRawBits() <= fix.getRawBits());
}
bool Fixed::operator!=(const Fixed &fix) const
{
return (this->getRawBits() != fix.getRawBits());
}
bool Fixed::operator==(const Fixed &fix) const
{
return (this->getRawBits() == fix.getRawBits());
}
Fixed Fixed::operator+(const Fixed &fix) const
{
Fixed ret(this->toFloat() + fix.toFloat());
return (ret);
}
Fixed Fixed::operator-(const Fixed &fix) const
{
Fixed ret(this->toFloat() - fix.toFloat());
return (ret);
}
Fixed Fixed::operator*(const Fixed &fix) const
{
Fixed ret(this->toFloat() * fix.toFloat());
return (ret);
}
Fixed Fixed::operator/(const Fixed &fix) const
{
Fixed ret(this->toFloat() / fix.toFloat());
return (ret);
}
Fixed& Fixed::operator++(void)
{
this->fixed_int++;
return(*this);
}
Fixed& Fixed::operator--(void)
{
this->fixed_int--;
return(*this);
}
const Fixed Fixed::operator++(int)
{
const Fixed ret(*this);
this->fixed_int++;
return(ret);
}
const Fixed Fixed::operator--(int)
{
const Fixed ret(*this);
this->fixed_int--;
return(ret);
}
Fixed& Fixed::min(Fixed &fix1, Fixed &fix2)
{
if (fix1 <= fix2)
return (fix1);
return (fix2);
}
const Fixed& Fixed::min(const Fixed &fix1, const Fixed &fix2)
{
if (fix1 <= fix2)
return (fix1);
return (fix2);
}
Fixed &Fixed::max(Fixed &fix1, Fixed &fix2)
{
if (fix1 >= fix2)
return (fix1);
return (fix2);
}
const Fixed &Fixed::max(const Fixed &fix1, const Fixed &fix2)
{
if (fix1 >= fix2)
return (fix1);
return (fix2);
}
std::ostream &operator<<(std::ostream &out, const Fixed &fix);