[Modern C++] 5.2.입출력, 첨자, 타입변환, 증감 연산자 오버로딩

윤정민·2023년 7월 3일
0

C++

목록 보기
16/46

1. friend 키워드

클래스 내부에서 다른 클래스나 함수들을 friend로 정의할 수 있는데, friend로 정의된 클래스나 함수들은 원래 클래스의 private로 정의된 변수나 함수에 접근 가능하다

  • friend는 짝사랑 같은 관계이기 때문에 클래스 A에서 클래스 B의 private 멤버에 접근 불가
class A {
private:
    void private_func() {};
    int private_num;
    
    friend class B;  //B는 A의 친구
    friend void func();  //func은 A의 친구
}

class B {

void func() {
    A a;
    //private 함수의 필드들이지만 친구이기 때문에 접근 가능
    a.private_num= 2;  
    a.private_func();
}

2. 입출력 연산자 오버로딩

  • 우리가 생성한 클래스를 기본 타입처럼 입출력 함수의 인자로 주고싶다면, ostream에서 연산자를 오버로딩 하면 됨
std::ostream& operator<<(std::ostream& os, const Complex& c) {
    os << " ( " << c.real << " , " << c.img << " ) ";
    return os;
}
  • 만약 Complex 클래스의 real과 img변수가 private일 경우, 위 처럼 바로 사용할 수 없으니 Complex 클래스 내부에서 std::ostream& operator<< 함수를 friend로 지정해줘야 함

3. 첨자 연산자

배열에서 원소를 지정시 []연산자를 사용한다. 우리가 만든 class에 적용하기 위해선 아래와 같이 원소의 배열을 만들어주면 된다.

char& MyString::operator[](const int index)
{
  return str.string_content[index];
}

4. 타입 변환 연산자(Wrapper)

Wrapper클래스는 무언가를 포장하는 클래스라는 의미인데 기본 자료형들을 객체로써 다루어야 할 때 사용된다. 예를 들어 Int형의 경우는 다음과 같이 구성된다.

class Int
{
  int data;
  
  public:
    Int(int data) : data(data) {}
    Int(const Int& i) : data(i.data) {}

}

이외에 많은 연산자들을 오버로딩하여 Int클래스를 완성할 수 있다. 하지만 그 많은 함수들을 오버로딩 하는건 힘든일이니(그리고 똑같은 기능을 또 작성하기 싫음) 그냥 Wrapper 클래스의 객체를 마치 'int 형 변수'라고 컴파일러가 생각하게 만들자. 타입 변환 연산자를 만들겠다는 말이다. 이렇게 만들면 operator+를 정의하지 않더라도 컴파일러가 가장 이 객체를 int형 변수를 변환 한 다음에 +를 수행할 수 있다.


타입 변환 연산자 정의법

operator (변환 하고자 하는 타입) ()
  • 예시
#include <iostream>

class Int
{
  int data;
  
public:
  Int(int data) : data(data) {}
  Int(const Int& i) : data(i.data) {}
  
  operator int() { return data; }
};

int main()
{
  Int x = 3;
  int a = x+4;
  
  x = a * 2 + x + 4;
  std::cout<< x << std::endl;
  
  return 0;
}

5. 전위, 후위 증감 연산자

같은 ++, --인데 어떻게 구분해서 오버로딩 해주는 것일까?

  • 전위 증감 연산자 오버로딩 방법
    • 값이 바뀐 자기 자신을 리턴할 것
operator++();
operator--();
  • 후위 증감 연산자 오버로딩 방법
    • x는 의미없이 전위, 후위를 구분하기 위해 넣어주는 인자
    • 값이 바뀌기 이전의 객체를 리턴할 것
      • 추가적으로 복사 생성자를 호출해야 되기 때문에 전위 증감 연산자 보다 느림
operator++(int x);
operator--(int x);

느낀점

아무것도 모를땐 매번 후위 연산자를 우선적으로 사용했는데 이제 전위 연산자를 우선적으로 써야겠다.

profile
그냥 하자

0개의 댓글