[C++] 함수와 참조 (feat. &, 별명)

2020. 6. 24. 04:13·🖥️ 컴퓨터공학 🖥️/C | C++
반응형

출처 => C++ How to Program (Detitel / Prenticehall) / 현재 그리고 미래지향적인 C++ 프로그래밍(장석우, 임정목 / 비앤씨에듀케이션)

함수의 인자 전달 방식

 

▶ 프로그래밍에서 함수를 사용할 때 변수, 즉 인자는 거의 필수 불가결하게 사용이 된다. 인자, 혹은 이 매개변수는 어떤 식으로 불러와서 사용이 되는걸까? 2가지의 방법이 있는데 값에 의한 호출과 주소에 의한 호출로 나뉘어진다.

 

값에 의한 호출로 객체 전달

 

▶ 순서는 다음과 같다.

 

1. 함수를 호출하는 쪽에서 객체를 전달한다. 

2. 함수의 매개 변수 객체 생성, 매개 변수 객체의 생성자는 호출되지 않는다.

3. 함수 종료, 매개 변수 객체의 소멸자를 호출한다.

 

▶ 값에 의한 호출 시, 매개 변수 객체의 생성자는 실행되지 않는데 그 이유는 호출되는 순간의 실인자 객체 상태를 매개 변수 객체에 그대로 전달하기 위해서이다. 

 

#include<iostream>
using namespace std;

class Circle {
	int radius;
public:
	Circle() {
		radius = 1;
		cout << "생성자 실행 radius=" << radius << endl;
	}
	Circle(int r) {
		this->radius = radius;
		cout << "생성자 실행 radius=" << radius << endl;
	}
	~Circle() {
		cout << "소멸자 실행 radius=" << radius << endl;
	}
	double getArea() {
		return 3.14 * radius * radius;
	}
	int getRadius() {
		return radius;
	}
	void setRadius(int radius) {
		this->radius = radius;
	}
};

void increase(Circle c) {
	int r = c.getRadius();
	c.setRadius(r + 1);
}

void main() {
	Circle waffle(30);
	increase(waffle);
	cout << waffle.getRadius() << endl;
}

 

▶ 코드 분석 시간! main( ) 함수에서부터 보자.

Circle waffle(30);
increase(waffle);

 

▶ Circle의 기능을 갖는 객체 waffle을 생성하였다. waffle의 반지름은 30이다. 이 waffle을 increase라는 매개변수로 넣어준다.(값에 의한 호출)

void increase(Circle waffle){
	int r=c.getRadius();
	c.getRadius(r+1);
}

 

▶ waffle의 반지름은 30이다. getRadius()메서드는 반지름을 int형으로 return 하므로 c.getRadius()의 값은 30이다.

 

▶ r+1이므로 c.getRadius(r+1)의 값은 31이다.

 

▶ 클래스 Circle의 객체인 waffle이 만들어지면서 생성자가 실행되었다. (1 번째 줄), 그리고 increase 메소드의 객체 c가 종료가 되면서 소멸자가 실행이 되고 그 때의 반지름은 r+1인 31이다. (2 번째 줄). 그리고 waffle.getRadius()의 결과인 30을 cout 명령어를 통해 출력한다. (3 번째 줄). 그리고 마지막으로 waffle객체가 종료가 되면서 소멸자가 실행이 된다. 이 때 waffle의 반지름은 30이다. (4 번째 줄)

 

주소에 의한 호출로 객체 전달

 

▶ 함수 호출시 객체의 주소만 전달하여 준다. 이 때의 함수의 매개변수는 객체에 대한 포인터 변수로 선언을 해준다.

void increase(Circle *c) {
	int r = c->getRadius();
	c->setRadius(r + 1);
}

void main() {
	Circle waffle(30);
	increase(&waffle);
	cout << waffle.getRadius() << endl;
}

 

▶ Class에 대한 내용은 같고, 주소로 호출을 하게 되면 위의 코드만 바뀐다. 

 

 

참조 변수

 

▶ 이미 존재하는 변수에 대한 다른 이름(별명)을 선언하는 개념이다.

 

▶ 참조 변수는 이름만 생기며 참조변수에 대한 새로운 공간을 할당하지 않는다. 또한 초기화로 지정된 기존 변수를 공유한다.

int n = 2;
int& refn = n;
//참조변수 refn 선언. refn은 n에 대한 별명

Circle c;
Circle& refc = c;
//참조변수 refc선언. refc는 circle에 대한 별명

 

▶ 기본 타입 변수에 대한 참조 예제

 

#include<iostream>
using namespace std;

void main() {
	cout << "i" << '\t' << "n" << '\t' << "refn" << endl;
	int i = 1;
	int n = 2;
	int& refn = n;
	//참조변수 refn선언. refn은 n에 대한 별명
	n = 4;
	refn++;//refn=5, n=5;
	cout << i << '\t' << n << '\t' << refn << endl;

	int* p = &refn;
	//p는 n의 주소를 가짐
	*p = 20;//refn=20, n=20
	cout << i << '\t' << n << '\t' << refn << endl;
}

 

 

 

 

▶ 객체에 대한 참조 예제

#include<iostream>
using namespace std;

class Circle {
	int radius;
public:
	Circle() { radius = 1; }
	Circle(int radius) {
		this->radius = radius;
	}
	void setRadius(int radius) {
		this->radius = radius;
	}
	double getArea() {
		return 3.14 * radius * radius;
	}
};

void main() {
	Circle c;
	Circle& refc = c;
	refc.setRadius(10);
	cout << refc.getArea() << " " << c.getArea();
	//refc나 c나 같기 때문에 결과는 314로 같다
}

 

 

참조에 의한 호출

 

▶ 참조를 가장 많이 활용하는 사례로써 call by reference라고 부른다

 

▶ 참조에 의한 호출 예제

#include<iostream>
using namespace std;

class Circle {
	int radius;
public:
	Circle();
	Circle(int r);
	~Circle();
	double getArea() {
		return 3.14 * radius * radius;
	}
	int getRadius() {
		return radius;
	}
	void setRadius(int radius) {
		this->radius = radius;
	}
};

Circle::Circle() {
	radius = 1;
	cout << "생성자 실행 radius=" << radius << endl;
}

Circle::Circle(int radius) {
	this->radius = radius;
	cout << "생성자 실행 radius=" << radius << endl;
}

Circle::~Circle() {
	cout << "소멸자 실행 radius=" << radius << endl;
}

void increaseCircle(Circle& c) {//참조 매개변수 c
	int r = c.getRadius();
	c.setRadius(r+1);
}

void main() {
	Circle waffle(30);
	increaseCircle(waffle);//참조에 의한 호출
	cout << waffle.getRadius() << endl;
}

 

 

728x90
반응형

'🖥️ 컴퓨터공학 🖥️ > C | C++' 카테고리의 다른 글

[C++] strcmp 함수를 이용한 문자열 비교 예제  (0) 2020.11.09
[C++] C++에서의 데이터타입, signed와 unsigned  (0) 2020.11.08
[C++] string 클래스 (feat. copy, getline, substr, find, replace)  (0) 2020.06.24
[C++] 예외 처리 (Exception)  (0) 2020.06.21
[C++] 조작자를 이용한 구조체 객체들의 정보 출력 프로그램(feat. struct, setw(), switch)  (0) 2020.06.21
'🖥️ 컴퓨터공학 🖥️/C | C++' 카테고리의 다른 글
  • [C++] strcmp 함수를 이용한 문자열 비교 예제
  • [C++] C++에서의 데이터타입, signed와 unsigned
  • [C++] string 클래스 (feat. copy, getline, substr, find, replace)
  • [C++] 예외 처리 (Exception)
공대생 배기웅
공대생 배기웅
군노답 미필 공대생 배기웅의 대학생활을 갈아 넣은 블로그
    반응형
  • 공대생 배기웅
    글쓰는공대생의 IT블로그
    공대생 배기웅
  • 전체
    오늘
    어제
    • 분류 전체보기 (166)
      • 🖊️ 공대생 글쓰기 🖊️ (17)
        • 공대생 회고록 (4)
        • 공대생의 끄적끄적 (4)
        • 슬기로운 공대생활 (9)
        • 무한도전 대학원생 (0)
      • 📈 산업공학 📈 (14)
        • 금융, 파생상품 (13)
        • 통계 (0)
        • 선형대수 (0)
        • 보험, 리스크관리 (0)
        • 재무회계 (1)
      • 🖥️ 컴퓨터공학 🖥️ (92)
        • 머신러닝, 딥러닝 (12)
        • 텐서플로우, 케라스 (1)
        • 알고리즘 (24)
        • 웹 (5)
        • Python (3)
        • C | C++ (23)
        • Java (15)
        • 코드 에러 모음집 (9)
      • 😙 취미, 교양 😙 (2)
        • 영어공부 (1)
        • 일본어회화 공부 (1)
      • 🔍 정보 공유 🔍 (38)
        • 대학생 외부활동 정보 (2)
        • 개발자관련 정보 (3)
        • 대입 논술 입시자료 정보 (22)
        • 프로그램 세팅 (11)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • [공지] 글쓰는 공대생입니다 😃
  • 인기 글

  • 태그

    자바
    acmicpc
    알고리즘
    예외
    프랜드함수
    조작자
    프로그래머스
    객체지향
    OOP
    무작위 변수
    재귀함수
    equals프레임워크
    경제성공학
    Operator
    이클립스
    데이터베이스
    C++
    Java
    스캐너
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
공대생 배기웅
[C++] 함수와 참조 (feat. &, 별명)
상단으로

티스토리툴바