본문으로 건너뛰기
모던 C++ 심화LESSON 13

값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기

난이도중급 → 심화
예상 시간70분
선수지식이전 강의

13강. 값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기

이번 강의에서 해결할 문제​

“복사를 피하려면 전부 참조” 같은 규칙은 작은 정수까지 간접 접근하게 만들고, 임시 객체를 장기 보관하는 댕글링을 숨깁니다. 함수 인자는 성능만이 아니라 수정 여부, null 가능성, 보관 기간과 소유권 이전을 표현해야 합니다.

학습 목표​

먼저 알아야 할 핵심 개념​

작고 복사 가능한 값은 값 전달이 기본입니다. 큰 필수 읽기 입력은 const T&, 필수 수정은 T&, 선택적 비소유 대상은 T*를 고려합니다. 함수가 값을 보관해야 한다면 값으로 받아 멤버로 이동하는 방식이 lvalue와 rvalue 호출을 함께 처리하기 쉽습니다. 단일 소유권 이전은 unique_ptr<T> 값으로 드러냅니다.

왜 이 문제가 위험한가​

임시 객체를 const 참조 멤버로 저장하거나 호출자 지역 객체의 포인터를 비동기 작업에 넘기면 호출 종료 뒤 댕글링이 됩니다. 반대로 모든 문자열을 값으로 여러 계층에 전달하면 불필요한 복사가 생길 수 있습니다. 저장 여부가 전달 방식의 핵심 분기입니다.

가장 작은 예제로 시작하기​

task_api.cpp
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

struct Task { std::string name; int priority{}; };

void printTask(const Task& task) {
std::cout << task.name << ':' << task.priority << '\n';
}

void raisePriority(Task& task, int amount) {
task.priority += amount;
}

class TaskService {
public:
void add(Task task) { tasks_.push_back(std::move(task)); }
private:
std::vector<Task> tasks_;
};

int main() {
Task task{"build", 2};
printTask(task);
raisePriority(task, 1);
TaskService service;
service.add(task); // 복사 후 내부 이동
service.add(Task{"test", 1}); // 임시값을 내부로 이동
}

코드 한 줄씩 이해하기​

  1. printTask는 호출 중 읽기만 하므로 const Task&가 맞습니다.
  2. raisePriority는 원본 수정이 필수라 Task&를 받습니다.
  3. 작은 int는 값 전달이 단순합니다.
  4. TaskService::add는 작업을 보관하므로 값으로 받아 내부 컨테이너로 이동합니다.
  5. lvalue 호출은 한 번 복사되고 임시값 호출은 이동 경로를 활용할 수 있습니다.

실행 결과와 메모리·동작 흐름​

출력은 build:2이고 이후 원본 우선순위는 3이 됩니다. service.add(task)는 원본을 유지하면서 서비스에 독립 값을 저장합니다. 두 번째 호출의 임시 작업은 호출 뒤 사라지지만 서비스에는 이동된 값이 남습니다.

단계별 실습​

흔한 실수와 해결 방법​

언제 사용하고 언제 피할까​

호출 중 읽기·수정만 하면 참조, 선택성이 있으면 포인터, 보관하면 값 또는 소유 포인터를 사용합니다. 구체 성능 차이가 중요한 경계는 벤치마크하되 수명 계약을 희생하지 않습니다.

게임 개발 연결​

프레임 안에서만 쓰는 입력과 다음 프레임까지 보관하는 작업 데이터는 전달 계약이 다릅니다. 비동기 경계에서는 특히 값이나 명시적 소유권을 우선합니다.

이해 점검 질문 3개​

  1. 함수를 값으로 받아 멤버로 이동하는 방식이 lvalue와 rvalue 호출을 어떻게 처리하나요?
  2. 호출 중에만 사용하는 포인터를 멤버로 저장하면 어떤 수명 문제가 생기나요?
  3. 작은 정수를 const 참조보다 값으로 받는 편이 단순한 이유는 무엇인가요?

핵심 요약​

다음 강의 연결​

14강. vector에서 값 컨테이너의 연속 저장과 재할당이 관찰자 수명에 미치는 영향을 다룹니다.

MINI QUIZ

값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기” 실습 결과를 해석하는 올바른 기준은 무엇인가요?
  2. 문제 2“값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기” 실습 중 ‘호출 중 포인터를 멤버에 저장’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

13강. 값·참조·포인터로 전달하기: 성능과 소유권을 함께 판단하기 미완료 상태