[C++] CPP Module 02

J_JEON·2022년 11월 24일
0

CPP

목록 보기
3/9

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;
    // fraction_bit 즉 8만큼 num을 왼쪽으로 비트연산하여 8비트 고정소수점기준 정수부로 밀어줌
}

Fixed::Fixed(const float num)
{
	std::cout << "Float constructor called" << std::endl;
	this->fixed_int = roundf(num * 256);
    // float는 비트연산을 하지못함
    // 때문에 8비트만큼 왼쪽으로 비트연산하는것과 같게 움직이도록 num에 256을 곱해줌
    // 이때 연산중 값을 버려서 정확한 값이 나오지않는 문제를 해결하기위해 roundf로 반올림 해줌
}

int Fixed::toInt( void ) const
// 고정 소수점을 정수로
{
	return (this->fixed_int >> this->fraction_bit);
    // 왼쪽으로 8비트 밀어준것을 다시 오른쪽으로 8비트 밀어 원래대로 돌리고 반환
}

float Fixed::toFloat( void ) const
// 고정소수점을 실수로
{
	return((float)this->fixed_int / (256));
    // 왼쪽으로 8비트 밀어준것을 다시 오른쪽으로 8비트 밀어 원래대로 돌리고 반환
}

std::ostream &operator<<(std::ostream &out, const Fixed &fix)
{
	out << fix.toFloat();
	return (out);
    // 고정 소수점 출력시 toFloat()을 적용해 부동소수점으로 값을 출력할 수 있도록 
    // ostream 클래스의 << 연산자를 오버로딩 해줌
}

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());
    // this가 더 크다면 true 반환
}

bool Fixed::operator<(const Fixed &fix) const
{
	return (this->getRawBits() < fix.getRawBits());
    // this가 더 작다면 true 반환
}

bool Fixed::operator>=(const Fixed &fix) const
{
	return (this->getRawBits() >= fix.getRawBits());
    // this가 더 크거나 같다면 true 반환
}

bool Fixed::operator<=(const Fixed &fix) const
{
	return (this->getRawBits() <= fix.getRawBits());
    // this가 더 작거나 같다면 true 반환
}

bool Fixed::operator!=(const Fixed &fix) const
{
	return (this->getRawBits() != fix.getRawBits());
    // this와 인자가 다르다면 true 반환
}

bool Fixed::operator==(const Fixed &fix) const
{
	return (this->getRawBits() == fix.getRawBits());
    // this와 인자가 같다면 true 반환
}

Fixed Fixed::operator+(const Fixed &fix) const
{
	Fixed ret(this->toFloat() + fix.toFloat());
	return (ret);
    // this와 인자의 num을 더하여 반환
}

Fixed Fixed::operator-(const Fixed &fix) const
{
	Fixed ret(this->toFloat() - fix.toFloat());
	return (ret);
    // this에서 인자의 num을 빼서 반환
}

Fixed Fixed::operator*(const Fixed &fix) const
{
	Fixed ret(this->toFloat() * fix.toFloat());
	return (ret);
    // this와 인자의 num을 곱하여 반환
}

Fixed Fixed::operator/(const Fixed &fix) const
{
	Fixed ret(this->toFloat() / fix.toFloat());
	return (ret);
    // this에서 인자의 num을 나누어 반환
}

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);
profile
늅늅

0개의 댓글