<객체> 5. 함수와 참조, 복사 생성자

정지민·2023년 10월 6일
0

객체 프로그래밍

목록 보기
5/11

인자 전달 방식

  • 값에 의한 호출
  • 주소에 의한 호출
    - 매개 변수는 포인터 타입, 주소를 넘겨주고 넘어온 주소값이 매개 변수에 저장

'값'에 의한 호출로 객체 전달

  • 호출하는 쪽에서 객체 이름만 사용
  • 호출받는 쪽에서 객체 그대로 복사, 매개 변수 객체의 생성자 호출되지 않음
  • 함수가 종료되면 매개 변수 객체의 소멸자 호출됨
    -> 생성자와 소멸자의 비대칭 구조
  • 생성자가 실행되지않는 이유는 매개변수 객체에 그대로 전달하기 위함
#include <iostream>
using namespace std;

class Circle {
private:
	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 increase(Circle c) {
	int r = c.getRadius();
	c.setRadius(r+1);
}

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

//결과
//생성자 실행 radius = 30
//소멸자 실행 radius = 31
//30
//소멸자 실행 radius = 30

'주소'에 의한 호출

  • 호출시 객체의 주소만 전달함
  • 매개변수는 포인터 변수로 선언
  • 생성자와 소멸자가 실행되지 않음

객체 치환

  • 동일한 클래스 타입의 객체끼리 치환 가능
  • 치환된 두 객체는 내용물만 같을 뿐 독립적인 공간 유지
Circle c1(5);
Circle c2(30);
c1 = c2;

객체 리턴

Circle getCircle() {
	Circle tmp(30);
	return tmp; // 객체 tmp 리턴
}
Circle c; // c의 반지름 1
c = getCircle(); // tmp 객체의 복사본이 c에 치환. c의 반지름은 30이 됨
#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; }
};

Circle getCircle() {
	Circle tmp(30);
	return tmp; // 객체 tmp을 리턴한다.
}

int main() {
	Circle c; // 객체가 생성된다. radius=1로 초기화된다.
	cout << c.getArea() << endl;

	c = getCircle(); 
	cout << c.getArea() << endl;
}

//결과
//3.14
//2826

참조 변수

  • 참조자 &
  • 참조변수는 이름만 생기며 새로운 공간을 할당하지 않음 (기존 변수를 공유)
#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; }
};

int main() {
	Circle circle;
	Circle &refc = circle; 
	refc.setRadius(10);
	cout << refc.getArea() << " " << circle.getArea();
}

//결과
//314 314

참조 매개 변수

  • 함수의 매개 변수를 참조 타입으로 선언
  • 참조 매개 변수의 이름만 생기고 공간이 생기지 않음, 실인자 변수 공간 공유 (같은공간 이름 2개)
#include <iostream>
using namespace std;

class Circle {
private:
	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) {
	int r = c.getRadius();
	c.setRadius(r+1);
}

int main() {
	Circle waffle(30);
	increaseCircle(waffle);
	cout << waffle.getRadius() << endl;
}

//결과
//생성자 실행 radius = 30
//31
//소멸자 실행 radius = 31

참조 리턴

  • 공간에 대한 참조 리턴
  • 변수의 값 리턴하는 것이 아님
#include <iostream>
using namespace std;

char& find(char s[], int index) {
	return s[index]; // 참조 리턴
}

int main() {
	char name[] = "Mike";
	cout << name << endl;

	find(name, 0) = 'S'; // name[0]='S'로 변경
	cout << name << endl;

	char& ref = find(name, 2); 
	ref = 't'; // name = "Site"
	cout << name << endl;
}

결과
//Mike
//Sike
//Site

얕은 복사

  • 동적 메모리 할당된경우 사본이 메모리를 공유하는 문제 발생
    -> 객체가 다른데 포인트가 똑같아 같은걸 바라보게됨

깊은 복사

  • 동적 메모리 할당된 경우 사본은 별도로 동적 할당

복사 생성자

  • 한 클래스에 오직 한 개 선언 가능
  • 클래스에 대한 참조 매개 변수를 가지는 독특한 생성자
class Circle {
	............
	Circle(const Circle& c); // 복사 생성자 선언
	............
};

Circle::Circle(const Circle& c) { // 복사 생성자 구현
	............
}

디폴트 복사 생성자

  • 복사 생성자가 선언되어 있지 않는 클래스

0개의 댓글