CPP_어소_53_클래스 (3)

CJB_ny·2022년 6월 29일
0

CPP_AROTHO

목록 보기
52/83
post-thumbnail

int a = 10;
int b = 100;
b = a;

이거는 값을 복사하는 것인데

이거는 뭔상황이노?

일단, 구조가 같다.

c3의 객체가 가지고있던 값들이 복사가 되지 않을까??


int같은 경우에는 "기본 자료형"이다.

그래서 c2 = c3이런경우에

(생성자들도 만들어주지 않으면 자동으로 만들어 줬던 것처럼)

내가 만들지 않아도 자동으로 만들어 주는게 더있다.

대입 연산자.

원래라면 사용자가 만들지 않았기 때문에 자동으로 만들어졌어야하는데

그걸지금 만들어 본 것이다.

그래서 c2 = c3 하면

break잡아보면 일로 들어옴.

객체끼리 더한다?

근데 이딴거 되나??

근데 나는 객체끼리 더한다는 의미가 각 객체의 멤버들끼리의 값의 합을 구하고 시픈데...(내 생각)

그래서 그런 경우에는 니가 직접 함수를 구현해라 이말이다.

그래서 c1 + c2; 이런거 안됨.

그래서 연산자를 호출했을 경우

SetInit처럼 기능(함수)가 필요하다.

따라서

대입연산자 제외하고 나머지 연산자 기능들은 직접 만들어 주어야 한다.

이거 오버로딩 하면됨.

내가 만든 자료형의 연산은 컴파일러가 인식 못함. ❗

c1 +(*, / ...) c2 를 하였을 때

해당 연산자의 기능을 "오버로딩" 하는 것임.

자료형& 이거는 뭐노? ❗

자료형 옆에 '&' 붙였는데

기호정리 ❗

포인터

  • 자료형 * 변수명;

    이런 자료형 포인터 타입의 변수명이다. => 포인터 변수 만들어짐

이렇게 만들어진 포인터 변수앞에 * 붙이면

  • *포인터변수

    포인터 변수에 저장되어있는 주소를 역참조 한다는 뜻 (== 값에 접근)

  • 모든 변수 앞에 &변수;

    주소값을 반환.

레퍼런스(참조) 변수 선언

  • 자료형 & 변수명

    C -> C++ 넘어오면서 원본에 접근 할 수 있는 방법이 하나 더 추가 되었는데
    이게 "레퍼런스"이다.

이게 지금 위랑 아래랑 비슷한 상황이다.

'&' 이거 어셈블리 뜯어보면 포인터랑 똑같이 동작함.

포인터 && '&' 가장큰차이

이 차이인데

int* const p = &a; 하면 포인터 변수가 상수화됨.

즉 p는 다른 주소값을 받을 수 없다.

레퍼런스도 마찬가지임.

여기서 뭔가를 수정하면

int& refA = a;
refA = 200;

이렇게하면 a의 값을 수정하는 상황이다.

레퍼런스

원본 참조한다.

참조하는 값을 안 바뀌게 하고 싶을 때

포인터로 치자면 const int* int형 값을 const해버림.

레퍼런스의 경우에도

const int& 해버리면 참조하는 것을 const => 수정이 불가능 하다.

이거랑 같은 말이다.

const int* const p2 = &a == const int& iRefConst = a;

레퍼런스는 태생이 const가 붙은애임.

const ref사용하는 이유 중요 ❗❗

const ref사용하는 이유는 const 포인터 쓰는 이유랑 똑같다.

내가 원본의 비용을 작게해서 "전달"해주고 싶을 경우.

원본이 굉장히 클 경우, 원본을 그대로 전달하면 "복사 비용"이 크다.

포인터 변수는 딱 "고정 사이즈"이다.

주소를 주면은 주소를 통해서 원본에 접근이 가능하기 때문에

그러니까, "참조 형태"로 주면은 원본에 대한 "참조"를 주는 것이기 때문에

원본 전체를 복사를 하는 비용을 줄일 수 있다.

그래서

받아간 쪽에서도 "참조 변수"를 통해서 "원본"을 수정하게되는 것이다.

그런데,

나는 수정되길 원하지 않고, 전달은 하 되, 값을 읽어볼 수 만 있게 전달하 되,

"수정"되고싶지는 않을 경우, => (const 포인터를 사용해서 인자 받았었음)

const ref를 사용해주면된다.

operator ❗

operator는 해당 클래스 == "MC쪽에 대입연산자가 발생했을 때, 호출되는 함수다"라는

뜻이다.

그런데 인자로,

operator인자

const MC& 참조 타입으로 왔음.

그런데 이 함수를 호출한 객체는 어디에 와있다고?

멤버함수안에 this 생략되어있음.

operator를 호출한 객체가 있을 것이고, 호출한 객체의 추가 인자로

const MC& other가 들어온 것이다.

지금 이 경우

c3가 대입 연산자를 호출한 "객체"이다.

그래서 operator의 this에는 누구의 객체이냐? => c3 이다.

그래서

this->m_i = _Other.m_i;
this->m_f = _Other.m_f;

this가 생략된 것이고

인자로 const CMy& _Other 에는 c2를 참조 받아서 온 것이다.

그런데 "대입"시킬 것이라 원본은 수정되면 안되니까 "const" CMy& _Other 이렇게

인자로 들어간 것임.

operator 반환타입 (수정)

반환타입에 reference가 있을 경우 어려워한다.

지금 MC& 가 반환타입인데

"참조"를 return 하겠다. 라는 뜻이다.

예시

이거는 지금 i3의 값을 i2에 넣고,

i2의 값을 i에다가 넣겠다라는 뜻이다.

그러면

i3에 있던 값이 i2에 들어가면서 연산의 순위상 지금 밑줄 부분의 연산이 끝났다.

끝나고 나면

이렇게 남은 상황이라 연산이 되는 것이다.

그래서 일케 수정할 경우 ❗

반환 타입이 없어서

c = c2 = c3 할 경우

c2 = c3는 되는데 반환타입이 없어서 그다음 연산인

c1 = c2가 안된다.

그래서

MC&라는 참조 타입을 반환을 하는데

return *this 에서 this라는 것은 현재 주소(포인터)이니까

'*'로 this에 접근을 해야 원본 객체인 c2를 말하는 것이고

이 c2를 참조해서 되돌려 주겠다! => 그래서 반환 타입이 MC&이다.

반환 되면 ❗

그래서 이 연산이 끝나면

원본인 c2가 반환되어서 온 것이다.

c2가 다시 c라는 객체가 호출한 operator의 인자로 c2가 들어가는 것이다.

그래서 operator의 반환타입이 이렇게 설계 되어야함.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글