연산자 오버로딩 & friend & C++ 스타일의 캐스팅

SOEUN CHOI·2022년 5월 27일
0

C++_study

목록 보기
4/15

씹어먹는 C++

6장 연산자 오버로딩(overloading) 188p - 269p


대표적 연산자

  • +, -, * 와 같은 산술 연산자
  • +=, -= 와 같은 축약형 연산자
  • >=, == 와 같은 비교 연산자
  • &&, || 와 같은 논리 연산자
  • -> 나 * 와 같은 멤버 선택 연산자 (역참조 연산자)
  • ++, -- 증감 연산자
  • [ ] 배열 연산자 와 () 함수 호출 연산자
  • = 대입 연산자

연산자 오버로딩(overloading)

연산자 오버로딩

기본 연산자들을 직접 사용자가 정의 사용

  • C++에서는 사용자 정의 연산자 사용 가능
    - 클래스 내부 or 전역 함수도 가능

    ※이항 연산자 (피연산자를 두개 취하는 연산자) 주의

  • 기본적이 format
    (리턴 타입) operator(연산자) (연산자가 받는 인자)

  • example code

    // == 
    bool MyString::operator==(MyString& str) {
    	return !compare(str); // str 과 같으면 compare 에서 0 을 리턴한다.
    }
    // << 
    std::ostream& operator<<(
    	std::ostream& os, const Complex& c) { os << "( " << c.real << " , " << c.img << " ) "; 
      	return os;
    }
    // +
    Complex operator+(const Complex& a, const Complex& b) {
    	Complex temp(a.real + b.real, a.img + b.img);
    	return temp;
    }
    // []
    char& MyString::operator[](const int index) { return string_content[index]; }
    
    	```
  • 주요 포인트

    • 두 개의 동등한 객체 사이에서의 이항 연산자는 멤버 함수가 아닌 외부 함수로 오버로딩 하는 것이 좋음
    • 두 개의 객체 사이의 이항 연산자 이지만 값의 변화가 동등하지 않는 이항 연산자는 멤버 함수로 오버로딩 하는 것이 좋음
    • 단항 연산자는 멤버 함수로 오버로딩 하는 것이 좋음
    • 일부 연산자들은 반드시 멤버 함수로만 오버로딩 해야함

타입 변환 연산자

사용자 정의 객체를 다른 자료형의 변수에 대입 하고자 사용

  • 기본적인 format
    operator (변환 하고자 하는 타입) ()

example code

#include <iostream>
class Int {
	int data;
	// some other 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;
}

friend

클래스나 함수에서 friend로 선언된 다른 클래스의 private 및 protected 멤버에 접근

클래스 private 인 경우 접근 불허 그러나 필요의 경우 해당 클래스나 함수에서 접근 가능하기 위해 사용

참고 : https://genesis8.tistory.com/98

friend 클래스

class 전체를 public으로 접근 가능
friend를 선언한 class에 해당 class에서 지정한 class가 접근가능

example code

class A{
public:
	A(){a=0;}
    friend B;
private:
	int a=0;
};

// class B에서 A의 private 접근 가능 
class B{
public:
	B(){b=0;}
    void print(A& classa){
    	cout<< classa.a<<endl;
        }
private:
	int b=0;
};

friend 맴버 함수

class 전체가 아닌 class의 특정 멤버 함수만 friend로 선언
friend를 선언한 class에 해당 class에서 지정한 class의 멤버 함수만 접근가능

class A{
public:
	A(){a=0;}
    friend void B::print(A% classa);
private:
	int a=0;
};

// class B에서 A의 private 접근 가능 
class B{
public:
	B(){b=0;}
    void print(A& classa){
    	cout<< classa.a<<endl;
        }
private:
	int b=0;
};

friend 전역 함수

접근 지정자를 무시하고 클래스 내부의 멤버에 접근


class B{
public:
	B(){b=0;}
private:
	int b=0;
    friend void print(B& classb){
    	cout<< classb.b<<endl;
        }
};

//class내 private 내부에 있지만 friend를 사용하므로써 외부에서 해당 멤버 함수 사용가능 

int main(){
	B bb;
    bb.print();
}

C++ 스타일의 캐스팅

4가지 종류

  • static_cast
    우리가 흔히 생각하는, 언어적 차원에서 지원하는 일반적인 타입 변환
  • const_cast
    객체의 상수성(const) 를 없애는 타입 변환. 쉽게 말해 const int 가 int로 바뀜
  • dynamic_cast
    파생 클래스 사이에서의 다운 캐스팅
  • reinterpret_cast
    위험을 감수하고 하는 캐스팅으로 서로 관련이 없는 포인터들 사이의 캐스팅

※ 생각보다 우리 코드에서 자주 보인다 알아두자

기본적인 format

(원하는 캐스팅 종류)<바꾸려는 타입>(무엇을 바꿀 것인가?)

example code

//static_cast 로 float 타입의 float_variable -> int 타입 변환
static_cast<int>(float_variable);
profile
soeun choi

0개의 댓글