Back-end/C++

22. 04. 05 - 이동 생성자, functor, 템플릿, 기본 자료구조, 네임 스페이스

giggs 2022. 4. 13. 14:11

 

이동 생성자 

  • C++ 에만 있는 – 새로 생긴 개념
  • 이런 게 있구나, 이런 상황에 작동하는구나, 사용하는구나 정도로 check

 

 

 

 

기본 세팅 -

  • 연산자 오버 로딩 :  배열과 배열을 더해주는 ' + ' 오버 로딩
  • 2개의 배열을 합칠 것인데, 배열의 사이즈와 값 입력하는 방법 check

 

 

 

 

배열과 배열을 더해주는 ' + ' 오버 로딩

 

 

operator +

 

 

합친 배열 size 

  • ( 원래 있던 배열 Array의 size ) + ( 들어온 배열 Array2의 size )  = 합친 배열 size

 

 

합친 배열 값 초기화 

  • ( 합친 배열 인덱스 0부터 ~ Array의 size 만큼 Array[ i ] 값들 다 넣어주고 ) +
  • ( Array의 size 끝난 부분부터 Array2의 size만큼 Array2[ i ] 값들 다 넣어준다)

 

 

 

 


 

 

 

작동 방식 test

 

 

DynamicArray 객체 3개 만들고 --- 각각 값을 넣고 ---플러스 + 연산

 

 

array = array2 + array3 의 메모리 상황 파악

 

 

 

58번 라인 - 임시 변수 Temp에 array2.size + array3.size 만큼 size가 생기고

60번 라인 – ( 0부터 ~ array2size만큼 ) Temp에 쭉 대입해준다.

64번 라인 – ( 대입끝난 array2 . size 부터 ) ~ ( array3 . size만큼 Temp에 쭉 대입 )

65번 라인 – i 에 있는 값이 _size 니까 (  i - _size = 0 ) 들어온 배열 array3[ 0 ] 부터 시작 의미

65번 라인 - i 에 있는 값이 20이니까 ( (i)20 - 20 = [0] )] , (21 - 20 = [1]) 이런식으로

68번 라인 - 우리가 만든 임시 변수 Temp는 operator + 안에서만 존재한다.

 

 

 

 


 

 

 

 

이 상태에서 + 연산 시작

 

 

 

 

 

덧셈을 하면 리턴 값(우리가 만든 임시 변수 Temp)을

담을 또 다른 임시 객체가 만들어질 것이다. - 복사 생성자를 통해 Temp를 복사해와야 한다.

이렇게 새롭게 만들어진 임시 객체는 array에 대입해주고 소멸할 것이다.

 

즉, 우리가 + 연산을 통해 만든 Temp라는 임시 객체를 array에게 대입 연산을 해주려면

 

Temp에서 또 다른 임시 객체로 넘겨주고 --- Temp 소멸

임시 객체는 array에게 넘겨주고 ---임시 객체 소멸

 

이런 경우

임시 변수에 동적 메모리 새롭게 만들지 않고

어차피 없어질 temp를 활용하여 그대로 받아와서

array에게 넘기고 소멸하도록 해준다

Temp에서 새로운 임시 객체로 넘겨주는 것이 아니라

Temp 가져와서 사용하고 array에게 넘겨주고 사라지도록 해준다.

( Temp에서 임시 객체로 넘겨주는 부분 생략 가능 )

 

 

이때 이동 생성자가 작동한 것이다.

 

 

 

 


 

 

 

이동 생성자 등장

 

 

 

&& 부분과 nullptr 체크

 

 

 

17번 라인 - &&의 의미 - 오른쪽 값을 참조하는 연산 - 오른쪽 값이란 임시적으로 만들었다가 사라지는 것

20~21번 라인 -ref로 들어온 객체의 사이즈와 주소 값 그대로 받는 과정

23번 라인 - ref로 들어온 객체는 원래 객체 사이즈와 주소 값 넘기고 사라질 애였다.

23번 라인 - ref . _ arr =  nullptr을 해주게 되면 이미 삭제된 애라고 인식된다.

23번 라인 - ref 객체의 소멸자 호출 시 nullptr의 값 0을 만나면 이미 삭제된 애라고 인식- 없어지지 않는다.

 

이때 이동 생성자 작동 - 임시 변수를 새로 만드는 것이 아니라 원래 있던 애 Temp를 계속 사용하도록 해준다.

 

 

 

 

 

 

 

임시 객체도 어차피 없어질 애- array에 넘겨주면 끝

 

 

 

 

 

 

개수 작으면 별 상관없지만 많다면 효율 증가

 

 

 

 


 

 

 

functor

 

 

  • 객체를 함수처럼 사용하는 것
  • 함수의 ( ) 연산자 오버 로딩
  • 객체를 함수처럼 사용하는 것
  • 객체를 함수의 매개변수로 전달해서 함수처럼 사용할 수 있는 것

 

 

 

 

 

 

 

 


 

 

 

 

템플릿 시작

 

  • 템플릿 이전에는 개발자가 다 만들어야 했다. ( 자료구조나 여러 가지 )
  • 탬플릿 이후에는 개발자가 만들지 않는다. ( 범용적으로 제공되는 자료구조 제공 )
  • 가져다 사용하면 된다.

 

 

 

예를 들어 add함수를 만든다고 하면, intfloat~~~ 다 만들어야 한다.

 

 

 

add 함수의 - int형 float형 double형

 

 

 

데이터 타입마다 다 만들어줘야 한다번거롭다.

 

 

 


 

 

템플릿 활용

  •  < > 안에 이름은 마음대로 해도 된다.

 

 

탬플릿을 이용한 add 함수

 

 

 

이렇게만 해주면 된다.

 

 

 


 

 

메인에서 테스트

 

 

 

add( ) 함수 내부 - int 타입 a,b,도 가능 - float 타입 c,d도 가능

 

 

컴파일러는 add함수를 만나면 우리가 만들어준 틀을 토대로 함수를 자동으로 만들어준다.

  • int a, b;일 때 add(a,b) 함수를 만나면 -> int add(int a,int b){ a+b}를 만들어 준 것
  • float a, b;일 때 add(a,b) 함수를 만나면 -> float add(float a,float b){ a+b}를 만들어 준 것

 

 

 

정확히 하려면 < > 안에 데이터 타입 입력 생략 가능

 

 

 

< 파란색 > 부분 통상적으로 생략

 

 

 


 

 

+ 정리

 

 

 

템플릿을 = 일반화 프로그램이라고도 한다.

  • 일반화란 – 공통된 것으로 묶는 것
  • 데이터 타입을 일반화한
  • 프로그래밍을 템플릿이라고 한다!

 

 

 

 

 

 

‘A‘ ’원‘ ’문자로 일반화(공통된 것으로 묶는 것)할 수 있다.

어떤 데이터 타입이 들어와도 가능하도록 데이터 타입들을 T로 일반화

 

함수의 기본 틀을 만들어주고 들어오는 데이터 타입에 맞춰서

컴파일러가 자동으로 함수를 만들어주도록 해주는 것!

 

 

 


 

 

 템플릿 특수화

 

 

DynamicArray라는 클래스가 내용이나 기능이 좋은데 int형 타입밖에 저장 못한다.

  • 이걸 float형도 받게 만드려 주려면?
  • class 안에는 class 또 있을 수 없다
  • 하나밖에 사용 못한다.
  • float 타입 받을 수 있는 DynamicArray Class를 하나 더 만들어야 한다.
  • ---
  • 이것 까진 ok 한다 해도

 

 

어떤 데이터 타입이 들어올지 모르는 상황에서는?

  • 템플릿으로 만들어준다!
  • int*를 T*로 바꿔준다

 

 

39번 Line 원래 코드 = int* _arr;

 

 

 

DynamicArray에 인트를 저장하고 싶다 하면 < > 안에 <int>

DynamicArrayfloat를 저장하고 싶다 하면 < > 안에 <float>

 

 

 

 


 

 

+@ 기본 타입 (int, float등)이 아닌 arrayStudent를 넣고 싶다면? 똑같이 < > 안에 넣어주면 된다.

 

 

 

 

이처럼 다이내믹 어레이에 어떤 타입도 사용 가능!

  • 템플릿 이전에는
  • 개발자가 필요한 데이터 타입에 맞는 다이내믹 어레이를 만들어줬어야 했다.
  • 시간도 오래 걸리고 size도 커진다.
  • but
  • 이제 템플릿의 활용으로 DynamicArray를 범용적으로 제공해준다.
  • 이것을 가져다 사용하면 되고, 여기에 내가 사용하는 데이터 타입을 넣어주면 된다.

 

 


 

 

 

기본자료구조 3가지 살펴보기

  • list, Queue, Stack

 

 

 

list

 

  • 배열은 처음에 크기 딱 정해져 있다.
  • 크기 알 수 없는 경우 순서대로 있는 것처럼
  • 앞 뒤에 있는 애들 서로 링크 주소 물게 만들어준다.
  • 동적으로 만들어주는 리스트

 

 

사용법 :

  • #include <list> 해주면 됨.
  • list < int > listArray; 만들고
  • push_back( )이라는 함수로 값을 넣어준다.
  • 접근하려고 할 때 iterator로 접근
  • iterator로 값 뽑아보기
  • remove로 몇 번째 지우기 가능

 

 

 

 


 

 

 

Queue

  • Input // Output 나오는 부분 다르다.
  • Enqueue // Dequeue
  • 대기열 구성할 때 사용

 

사용법 :

  • 스택 사용하려면 #include <stack>
  • 값을 넣을 때 push( )
  • 값 빼볼 때는 pop( ) 
  • 값을 살짝 볼때는 top( )

 

 

 

 


 

 

 

Stack

  • 데이터 들어가고 나가고 하는 부분 같다.
  • 항아리 구조

 

 

사용법 :

  • #include <queue>
  • 값을 넣을 때 push( ) // enqueue( )
  • 값을 뺄 때 pop( )
  • 값을 살짝 볼때는 front( ) // dequeue( )

 

 

 

 

 

 


 

 

 

 

네임스페이스 시작

 

 

한 공간에서

  • A라는 사람이 Math라는 클래스를 만들었다.
  • B라는 사람이 Math라는 클래스를 만들었다.
  • C라는 사람이 Math라는 클래스를 만들었다.

 

겹치는 상황 발생 – 이 상황에서는 A, B, C 한 공간에 있으므로 서로 조율 가능

 

 

BUT!

 

 

프로젝트가 커지면 여러 팀과 여러 공간이 생긴다.

  • 이것을 합쳐서 하나로 만드는데 – Merge
  • 같은 클래스나 변수명으로 인하여 충돌 발생,
  • 에러 발생 - 코드 수정의 책임과 시간의 문제 등으로 
  • 협력 기관, 협력자와 서로 싸우는 상황 발생할 수도 있다.
  • 이름, 변수 충돌로 에러 상황이 많이 발생함에 따라 나온 개념이
  • namesapce

 

 

 


 

 

 

각각 부여받은 namespace 안에 class를 생성

 

 

 

namespace Samsung

 

 

namespace LG

 

 

Math 함수 이름은 같지만

  • Samsung :: Math
  • LG :: Math로
  • 완전히 다른 것이다!

 

 

 


 

 

 

+@ namespace의 위치

 

 

 

 

 

 

 

using namespace Samsung 해주면

Samsung :: 생략 가능!

 

이처럼 using namespace는 사용하는 곳에 써주는 것이 기본

그러면 컴파일러 시간도 줄일 수 있다.

 

 

 

 


 

 

 


review



c++ 강의의 마지막 시간이었다.
원혁희 강사님 감사합니다~

마지막 시간 남은 진도를 빼느라 뒷부분은 스피드 하게 지나갔다.ㅎㅎ
다행히 한 번씩 봤던 개념들이라 이해하는 데는 큰 무리가 없었다.

C++의 이동 생성자.
아직 완벽히 이해한 것 같지가 않다.
그래서 정리하는 데에도 시간이 걸렸다.
흠. 일단은 작동하는 원리와 사용하는 방법
잘 체크해놓고, 더 찾아보도록 하자!

템플릿은 제네릭과 같은 기능이었고
궁금했던 namespace 도 알 수 있어서 좋았다.

한 달 정도의 짧은 시간이었지만
C++ 만의 기능들도 배울 수 있어서 좋았고
무엇보다도
java에서 따라서만 사용했던 변수나 함수들이
메모리 상으로 어떻게 작동되는지
알고 이해할 수 있었다는 점이 제일 좋았다.


기회가 된다면 C++도 더 배워보고 싶다.
일단은 이제 시작되는 java 교육에 집중하기로 ㅎㅎ