1. 값에 의한 호출방법 : 값에 의한 호출은 실인자의 값을 함수 매개 변수에 복사한다. 매개변수와 실인자는 서로 다른 공간을 독립적으로 사용한다. 그렇기 때문에 함수 내에서 실인자를 손상 시키는 일은 없다.


2. 주소에 의한 호출방법 : 주소에 의한 호출은 함수 호출 시 주소가 매개 변수로 전달된다. 매개변수와 실인자는 공간을 공유한다. 실인자의 주소를 넘겨주어 의도적으로 함수 내에서 실인자의 값을 변경하고자 할 때 이용 될 수 있다.


3. 참조에 의한 호출방법 : 참조 변수를 선언하여 사용한다. 참조 변수를 선언할때는 &기호를 사용한다. 참조 변수란 이미 선언된 변수에 대한 별명(alias)이다. 참조 변수가 선언될 시 이름만 생성되며 별도의 공간이 할당되지 않는데 원본 변수의 공간을 공유한다.


참조 변수 선언 시 주의 사항이 있는데, 어떤 변수에 대한 참조인지 초기화를 시켜주어야 한다. 그리고 참조 변수는 공간을 별도로 할당하지 않기 때문에 배열을 만들 수 없다.


4. 값에 의한 호출 예(예제 5-1, 값에 의한 호출의 문제점 정리)


#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) { // c라는 독립적인 공간을 사용하기 때문에 

int r = c.getRadius(); // 매개변수에는 다시 선언하며 받아준다. 

c.setRadius(r+1); // 하지만 생성자는 호출하지 않는다. 

} // 눈에 보이지 않지만 복사 생성자란 녀석이 있음 


int main(int argc, char** argv) {

Circle waffle(30);

increase(waffle);

cout << waffle.getRadius() << endl;

system("pause");

return 0;

}



5. 참조에 의한 호출 예제(예제 5-3, 소스, 결과, 주석)


#include <iostream>

using namespace std;


int main(int argc, char** argv) {

cout << "i" << '\t' << "n" << '\t' << "refn" << endl;

int i = 1;

int n = 2;

int &refn = n; //참조변수 refn을 선언. refn은 n의 별칭과 같은 것이다. 

n=4; //refn은 n의 공간을 공유하기 때문에 n이 4가 되면 refn도 4가 된다. 

refn++; //refn이 1이 증가하면 n도 증가, 5 와 5가 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 5 5

refn = i; //refn에 i의 값을 대입시킨다.refn과 n 그리고 i 모두 1이 된다. 

refn++; //refn이 증가하면 n도 같이 증가한다. refn과 n은 2가 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 2 2

int *p = &refn; //p가 refn의 주소를 가진다. 즉 p는 n의 주소를 가진다. 

*p = 20; //p가 가르키는 곳이 20이 된다. 즉 refn과 n 둘다 20이 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 20 20

return 0;

}



6. 참조에 의한 호출의 장점(예제 5-5, 소스, 결과, 주석)


#include <iostream>

using namespace std; 


bool average(int a[], int size, int &avg){ //참조 매개 변수 avg를 사용 

if(size <= 0){

return false;

}

int sum = 0;

for(int i=0 ; i<size ; i++){

sum += a[i];

}

avg = sum/size;

return true;

}


int main(int argc, char** argv) {

int x[] = {0,1,2,3,4,5};

int avg;

if(average(x, 6, avg)){ //참조 매개 변수를 사용하기 때문에 간단히 변수를 넘겨주기만 하면 값이 실제로도 바뀌기 때문에 좋다. 

cout << "평균은 " << avg << endl; //함수 내에서도 참조 매개 변수를 보통 변수처럼 사용 하기 때문에 작성하기 쉽고 보기 좋은 코드가 된다는 장점이 있다. 

}

else

cout << "매개 변수 오류 " << endl;

if(average(x, -2, avg)){

cout << "평균은 " << avg << endl;

}

else

cout << "매개 변수 오류 " << endl;


return 0;

}



+ Recent posts