본문으로 건너뛰기
모던 C++LESSON 19

코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준

난이도초급 → 중급 입문
예상 시간45분
선수지식이전 강의

19강. 코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준

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

모든 함수 인자를 포인터로 받으면 null 여부와 소유권을 매번 추측해야 합니다. 모든 값을 복사하면 큰 객체 비용과 수정 결과가 사라질 수 있습니다. 타입 선택은 성능 요령보다 함수 계약을 읽게 하는 도구입니다.

학습 목표​

  • 값 전달, 참조 전달, 포인터 전달의 기본 의미를 구분합니다.
  • 필수 입력과 선택 입력을 시그니처에 표현합니다.
  • 작은 값 복사와 큰 객체 참조를 상황에 맞게 선택합니다.

먼저 알아야 할 핵심 개념​

값 인자는 독립 복사본이며 함수가 바꿔도 호출자 값은 그대로입니다. 참조는 반드시 존재하는 객체의 별칭으로 사용하며 const T&는 복사 없이 읽습니다. 포인터는 nullptr로 대상 없음이 가능하고 다른 대상을 가리킬 수 있습니다. raw pointer 인자는 기본적으로 소유권 이전이 아니라 관찰로 문서화합니다.

가장 작은 실행 가능한 예제​

parameter_intent.cpp
#include <iostream>
#include <string>

struct Player {
std::string name;
int health;
};

int doubled(const int value) {
return value * 2;
}

void heal(Player& player, const int amount) {
player.health += amount;
}

void inspect(const Player* player) {
std::cout << (player == nullptr ? "no player" : player->name) << '\n';
}

int main() {
Player hero{"Mina", 70};
heal(hero, doubled(10));
inspect(&hero);
inspect(nullptr);
std::cout << hero.health << '\n';
}

핵심 코드 줄별 설명​

  1. 작은 정수는 값으로 받아 독립 계산합니다.
  2. heal은 반드시 존재하는 플레이어 원본을 수정해 Player&를 사용합니다.
  3. 검사 대상은 없을 수 있어 포인터로 받습니다.
  4. 포인터 함수는 역참조 전에 null을 처리합니다.
  5. 어느 함수도 플레이어 소유권을 가져가지 않습니다.

실행 결과와 값 변화​

Mina
no player
90

heal을 Player player 값 인자로 바꾸면 함수 내부 복사본만 90이 되고 마지막 출력은 70으로 남습니다.

단계별 실습​

실습 목표​

아이템 조회·수정 함수에 의도가 맞는 인자 타입을 선택합니다.

시작 전 상태와 실행 방법​

이름과 수량이 있는 Item 구조체를 준비합니다.

1단계: 최소 코드 작성​

작은 할인율은 값으로, 아이템 읽기는 const Item&로 받는 출력 함수를 만듭니다.

2단계: 값 또는 조건을 바꿔 결과 비교​

수량 변경 함수를 값과 참조로 각각 작성해 원본 차이를 확인합니다.

3단계: 작은 기능 확장​

선택된 아이템이 없을 수 있는 출력 함수는 const Item*로 받고 null을 처리합니다.

4단계: 스스로 해결하기​

문자열 이름을 값, const string&, string_view 중 무엇으로 받을지 함수가 보관하는지 여부를 기준으로 선택하세요.

막혔을 때​

const 참조에서 멤버를 수정할 수 없다는 오류는 읽기 전용 계약이 작동한 결과입니다. 수정이 요구사항인지 다시 확인한 뒤에만 비const 참조로 바꿉니다.

흔한 실수와 해결 방법​

  • 포인터가 빠르다는 이유만으로 사용: null 가능성과 수명 추적 비용이 생깁니다.
  • 수정 결과가 필요한데 값 전달: 원본을 수정해야 한다면 참조 또는 반환값을 사용합니다.
  • raw pointer로 소유권 전달: 소유권 이동은 unique_ptr 등 명시적 타입으로 표현합니다.

게임 개발 연결​

대미지 값은 값, 반드시 존재하는 캐릭터 수정은 참조, 선택 타깃 관찰은 포인터처럼 계약을 나눌 수 있습니다. 엔진 API의 객체 포인터는 GC·스레드·유효성 규칙이 추가되므로 일반 C++ 포인터 판단에 엔진 계약을 함께 적용합니다.

이해 점검 질문 3개​

  1. 값 인자를 수정해도 호출자 객체가 바뀌지 않는 이유는 무엇인가요?
  2. 필수로 존재하는 수정 대상에 참조가 어울리는 이유는 무엇인가요?
  3. raw pointer 인자와 unique_ptr 인자가 소유권 측면에서 어떻게 다른가요?

핵심 요약​

인자 타입은 복사·필수 대상·선택 대상·소유권을 표현합니다. 미세 성능보다 호출자가 계약을 바로 읽고 잘못된 상태를 만들기 어렵게 하는 선택을 우선합니다.

다음 강의 연결​

20강. 인벤토리와 퀘스트 도구에서 지금까지 배운 값 타입, 컨테이너, optional, 알고리즘과 단일 소유권을 하나의 프로그램으로 통합합니다.

MINI QUIZ

코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준 미니 퀴즈

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

0 / 2
  1. 문제 1“코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준” 작업 전 검토에서 채택해야 할 안전 기준은 무엇인가요?
  2. 문제 2“코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준” 실습 중 ‘raw pointer로 소유권 전달’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

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

19강. 코드 읽기 좋은 설계: 값, 참조, 포인터를 구분하는 기초 기준 미완료 상태