같은편
홍익대 게임소프트웨어전공의 프로그래밍 단련 공간
같은편
깃허브 주소
https://github.com/madongchan
GitHub 아이콘
  • 분류 전체보기 (85)
    • 게임 프로그래밍 패턴 (2)
    • C# 프로그래밍 (26)
    • C++ 프로그래밍 (32)
      • 함수 (8)
      • 클래스 (22)
    • 알고리즘 공부 (2)
      • codingame 사이트 문제 (11)
    • 유니티엔진 - 게임 공부 (3)
    • 언리얼엔진 - 게임 공부 (4)
    • 쓸모 있을 수 있는 팁 (2)
    • 일상이야기 (3)

최근 댓글

태그

  • 언리얼
  • 비동기
  • 클래스
  • 객체
  • 탐욕 알고리즘
  • 언리얼엔진4
  • 복사 생성자
  • c++
  • 알고리즘
  • queue
  • 문제 풀이
  • 람다식
  • 언리얼엔진
  • DFS
  • 스레드
  • 함수
  • 예외 처리
  • 최단 경로
  • task
  • C#

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
같은편

홍익대 게임소프트웨어전공의 프로그래밍 단련 공간

함수의 설계와 객체의 복사
C++ 프로그래밍/클래스

함수의 설계와 객체의 복사

2022. 7. 28. 16:57

전 책에서 이 부분을 좋아합니다. 왜냐하면 이 책을 읽지 않았더라면 평생 모르고 생각하지도 않고 살았을 테니까요.

같은 기능의 함수라도 매개변수와 반환형을 다르게 할 수 있고 그거에 따른 복사 생성자와 대입 연산자 사용 횟수를

저는 절대 생각하고 깨닫지 못했을 거니까요. φ(◎ロ◎;)φ

 

여기 Complex 클래스가 정의돼있습니다.

class Complex {
	double real, imag; // 복소수의 실수부와 허수부
public:
	Complex(double r = 0, double i = 0) : real(r), imag(i) { }
	//...
};

void main() {
	Complex a(1,2), b(3,4), c;
}

복소수 객체 a와 b를 더해 c에 저장하려고 합니다. 물론 계산 후 a와 b는 값이 변경되면 안 되고 c만 변경되어야 합니다.

 

이를 위한 방법은 크게 2가지로 구현할 수 있습니다.

  1. 절 자치 향적인 방법(일반 함수)
    • 결과를 반환하지 않는 방법 : 4가지
    • 결과를 반환하는 방법 : 3가지
  2. 객체지향적인 방법(Complex의 멤버 함수)
    • 결과를 반환하지 않는 방법 : 3가지
    • 결과를 반환하는 방법 : 3가지 

▶일반 함수로 구현


함수 원형 설계 사용 방법 복사 생성자 대입 연산자
void add(Complex,
Complex, Complex*);
add(a, b, &c); 2 0
void add(Complex*,
Complex*, Complex*);
add(&a, &b, &c); 0 0
void add(Complex,
Complex, Complex&);
add(a, b, c); 2 0
void add(Complex&,
Complex&, Complex&);
add(a, b, c); 0 0

일반 함수로 add() 구현하는 방법들(결과를 반환하지 않음)

 

값이 변경되지 않아야 하는 a와 b는 객체(Complex)나 포인터(Complex*) 또는 참조자(Complex&) 중 어느 형태로 전달해도 상관없습니다.

그러나 c는 반드시 Complex*나 Complex&로 전달해야 합니다. 값을 변경하려면 당연히 이렇게 해야 합니다.

그냥 객체로 보내면 객체가 매개변수로 복사가 된 거라 c가 변경되지는 않습니다.

그리고 대입 연산자는 사용되지 않습니다.

그리고 객체로 전달하면 복사 생성자가 호출되는 것에 유의해야 합니다.

두 번째 네 번째 방법으로 하면 전혀 호출되지 않습니다.


함수 원형 설계 사용 방법 복사 생성자 대입 연산자
Complex add(Complex, Complex); c = add(a, b); 3 1
Complex add(Complex*, Complex*); c = add(&a, &b); 1 1
Complex add(Complex&, Complex&); c = add(a, b); 1 1

일반 함수로 add() 구현하는 방법들(결과 반환)

 

먄약 add()가 결과를 반환하려면 반드시 반환 자료형은 객체(Complex)가 되어야 합니다.

객체의 주소나 참조자를 함수에서 반환하기 위해서는 그 함수가 끝나도 소멸되지 않는 객체여야 합니다.

이러한 함수를 사용하려면 반드시 대입 연산자가 사용되어야 합니다.

그리고 매개변수와 반환형에 있는 Complex의 수만큼의 복사 생성자가 호출됩니다.



일반 함수로 구현한 총 7가지의 방법 중 어떤 것이 가장 좋을까요?

저는 복사 생성자와 대입 연산자를 사용하지 않는 방법을 추천합니다.

특히 최근 코드의 복잡도를 줄이기 위해 포인터보다는 참조자를 추천합니다.

이것을 구현한 코드

void add(Complex& a, Complex& b, Complex& c){
	c.real = a.real + b.real;
    c.imag = a.imag + b.imag;
}

 

▶멤버 함수로 구현


함수 원형 설계
(Complex 클래스의 멤버 함수)
사용 방법 복사 생성자 대입 연산자
void add(Complex, Complex,); add(a, b); 2 0
void add(Complex&, Complex&); add(a, b); 0 0

멤버 함수로 add() 구현하는 방법들(결과를 반환하지 않음)

 

일반 함수에서 멤버 함수로 구현하고 클래스 내에서 구현하니까 c의 값을 불러낼 필요가 없으니 매개변수가 하나 줄어든 거 빼곤 변한 게 없다.

표에 포인터는 특별한 장점이 없으니 생략했다. 쓸 수는 있습니다.


함수 원형 설계
(Complex 클래스의 멤버 함수)
사용 방법 복사 생성자 대입 연산자
Complex add(Complex); c = a.add(b); 2 1
Complex add(Complex&); c = a.add(b); 1 1
Complex operator + (Complex&); c = a + b; 1 1

멤버 함수로 add() 구현하는 방법들(결과 반환)

 

모든 함수에서 복사 생성자가 호출되고, 대입 연산자도 사용됩니다.

특히 세 번째 방법은 연산자 중복 정의 기법을 사용하였습니다.



멤버 함수도 복사 생성자와 대입 연산자를 사용하지 않은 방법을 추천합니다.

이것을 구현한 방법은

void add(Complex& a, Complex& b){
	real = a.real + b.real;
    imag = a.imag + b.imag;
}

 

 

복소수 하나를 더하기 위해 이렇게 많은 방법이 있는 거에 처음엔 짜증이 확 났습니다.

내가 이걸 왜 하고 있냐고 생각도 했는데, 게임을 구현하다 보니 함수를 구현할 때 잘 구현하는 게 중요하다는 걸

깨닫고 이후로 받아들였습니다.

 

책은 함수의 설계에 대해 다음을 강조하고자 합니다.

  • 가능한 한 복사 생성자의 호출을 피하는 방법으로 구현하는 것이 안전하다.
    예를 들어, c.add(a, b)가 c = a.add(b) 보다 유리하고 안전합니다.

 

  • 매개변수로 객체(Complex)를 보내는 것보다 참조자(Complex&)가 유리합니다.
    그리고 전달된 객체를 수정하지 못하도록 상수형(const Complex&)으로 선언하는 것이 가장 좋습니다.

 

  • 연산자 중복을 이용하면 두 객체를 더하기 위해 c = a + b;와 같은 문장을 사용할 수도 있습니다.
    그러나 이를 위해서는 객체의 반환이 필요합니다.
    이와 같은 방법은 제한적으로 사용하는 것이 바람직하며, 함수는 가능하면 단순하고 안전하게 구현하는 게 좋습니다.

 

  • 복사 생성자가 필요한 경우에도 대부분은 디폴트 복사 생성자를 사용하면 됩니다.
    그러나 "깊은 복사"가 필요한 경우는 디폴트 복사 생성자를 사용할 수 없으며 개발자가 구현해 주어야 합니다.
저작자표시 비영리 변경금지 (새창열림)

'C++ 프로그래밍 > 클래스' 카테고리의 다른 글

상속  (0) 2022.08.08
.과 ->의 쓰는 용도  (0) 2022.08.04
얕은 복사와 깊은 복사  (0) 2022.07.28
객체의 복사와 복사 생성자  (0) 2022.07.28
객체 생성되는 것과 안 되는 것  (0) 2022.07.25
    같은편
    같은편
    책을 통해 이때까지 블로그나 유튜브에서 얻었던 지식의 파편들을 정립하고 합쳐 단단한 발판으로 만들기 위한 블로그

    티스토리툴바