C++ 7주차 참조와 함수 중복
참조
참조에 의한 호출
함수의 매개변수를 참조 타입으로 선언
형식
변수타입 함수명(변수타입 &변수명)
예시
1
void testFunc(int &n1, int &n2);
참조의 호출 필요한 경우
- 반환되는 데이터가 여러 종류인 경우
- 값 or error정보
참조를 이용한 반환
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#include <iostream> using namespace std; bool average(int arr[], int size, int& avg) { if (size <= 0) return false; int sum = 0; for (int i = 0; i < size; i++) sum += arr[i]; avg = sum / size; return true; } int main() { start: int arrNum, avg; cout << "숫자의 갯수를 입력해주세요>>"; cin >> arrNum; int* numArr = new int[arrNum]; for (int i = 0; i < arrNum; i++) { cout << i << "번째 숫자를 입력해주세요>>"; cin >> numArr[i]; } if (average(numArr, arrNum, avg)) cout << avg << endl; else { cout << "숫자의 수가 0 이하입니다. 처음으로 돌아갑니다" << endl; goto start; } }
결과
1 2 3 4 5
숫자의 갯수를 입력해주세요>>3 1번째 숫자를 입력해주세요>>6 2번째 숫자를 입력해주세요>>2 3번째 숫자를 입력해주세요>>1 3
참조를 이용한 객체 전달
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <iostream> using namespace std; class Circle{ private: int rad; public: Circle(): Circle(5){} Circle(int r) { rad = r; cout << "클래스 생성됨.\n반지름 : " << rad << endl; } ~Circle(){ cout << "소멸자 호출됨.\n반지름 : " << rad << endl; } int GetRad(){ return rad; } int SetRad(int r){return rad = r; } }; void IncreaseRad(Circle &c) { int rad = c.GetRad(); c.SetRad(++rad); } int main() { Circle circle; IncreaseRad(circle); cout << circle.GetRad() << endl; }
결과
1 2 3 4 5
클래스 생성됨. 반지름 : 5 6 소멸자 호출됨. 반지름 : 6
참조 리턴
C언어의 함수 리턴
함수는 반드시 값만 리턴
기본 타입값: int, char, double….
포인터 값
C++의 함수 리턴
함수는 값 외에 참조 리턴 가능
참조 리턴
- 변수 등과 같이 현존하는 공간에 대한 참조 리턴함
- 변수의 값 리턴하는 것이 X
- 변수 등과 같이 현존하는 공간에 대한 참조 리턴함
객체의 복사
#### 얕은 복사(Shallow Copy)
- 포인터만 복사
- 동적 할당을 받은 변수의 주소 값을 공유함
깊은 복사(Deep Copy)
- 포인터 메모리도 복사
- 복사 된 이후, 개별적인 객체가 되어 복사 대상이 바뀌더라도 영향이 없음
### 복사 생성자
특징
객체의 복사 생성시 호출되는 생성자
한 클래스에 한 개만 선언 가능(함수 중복 불가)
클래스에 대한 참조 매개 변수 가짐
구현 방법
1
2
3
4
5
6
class 클래스명{
클래스명(const 클래스명& 객체명); //복사 생성자의 선언
}
//복사 생성자의 구현
클래스명::클래스명(const 클래스명& 객체명);
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;
class Square {
private:
int length;
public:
Square(const Square& s);
Square() :Square(5) {};
Square(int l) { length = l; }
int GetArea() { return length * length; }
};
//복사 생성자
Square::Square(const Square& s) {
this->length = s.length;
cout << "복사 생성자 실행됨" << endl;
}
int main() {
Square b1;
Square b2(b1);
cout << "b1의 면적>>" << b1.GetArea() << endl;
cout << "b2의 면적>>" << b2.GetArea() << endl;
}
결과
1
2
3
복사 생성자 실행됨
b1의 면적>>25
b2의 면적>>25
디폴트 복사 생성자
선언하지 않을 경우, 컴파일러가 자동으로 생성
다형성 (Polymorphism)
함수 중복
동일한 이름의 함수 사용 가능
But 변수 타입 or 개수의 차이가 있어야 함
리턴 타입은 함수 중복과 관계가 없음
동일한 이름의 함수 사용 -> 함수 이름 구분 필요 없다는 장점
오버로딩
함수 간에 함수 중복
예시
1 2 3 4 5 6 7
//올바른 예시 int(int a, int b) { return a+b;} int(char a, char b) {return a+b;} //틀린 예시 double(int a, int b) { return a+b;} //리턴타입은 함수 중복과 관련 없음 int(char a, char b) {return a+b;}
오버라이딩
상속받은 객체간 함수 중복
소멸자는 함수 중복 불가
매개변수 보유 X
디폴트 매개 변수
특징
- 매개 변수 값 전달하지 않은 경우 호출된 함수에서 갖게 되는 디폴트 값
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//선언부
void TestVoid(int id=0, string name="Test"){
cout << "ID>>" << id << endl;
cout << "이름>>" << name << endl;
}
//호출부
TestVoid();
TestVoid(2021, "김");
//결과
ID>>0
이름>>Test
ID>>2021
이름>>김
제약사항
일반 매개 변수 앞에 선언 불가함
일반 매개변수 뒤에 선언되어야 함
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.