항목 20 ] '값에 의한 전달'보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다
'값에 의한 전달'보다는 '상수객체 참조자에 의한 전달' 방식이 대개 낫다
CALL BY REFERENCE vs CALL BY VALUE
사본을 주고받는 값에 의한 전달은 고비용의 연산이다.
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
|
class Person
{
public:
Person();
virtual ~Person();
private:
std::string name;
std::string address;
};
class Student : public Person
{
public:
Student();
virtual ~Student();
private:
std::string schoolName;
std::string schoolAddress;
};
bool validateStudent(Student s)
{
// TODO:
}
void main()
{
Student plato;
bool platoIsOK = validateStudent(plato);
}
|
cs |
위의 함수가 호출될 때 어떤 일이 일어날까요?
매개변수 s를 초기화시키기 위해 plato로부터 Student의 복사 생성자 호출
validateStudent가 복귀할 때 s는 소멸됨
매개변수 전달 비용
Student의 복사 생성자 호출 한 번
Person의 복사 생성자 호출 한 번
String 복사 생성자 네 번
소멸자도 마찬가지 => 총 생성자 여섯 번, 소멸자 여섯 번
참조자로 전달하자.
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
|
class Person
{
public:
Person();
virtual ~Person();
private:
std::string name;
std::string address;
};
class Student : public Person
{
public:
Student();
virtual ~Student();
private:
std::string schoolName;
std::string schoolAddress;
};
bool validateStudent(const Student& s)
{
// TODO:
}
void main()
{
Student plato;
bool platoIsOK = validateStudent(plato);
}
|
cs |
bool validateStudent(const Student& s);
새로 만들어지는 객체가 없기 때문에 생성자와 소멸자가 전혀 호출되지 않음
const가 붙어서 validateStudent 함수 안에서 객체가 변경될 걱정을 할 필요가 없음
복사손실 문제가 없어짐
파생 클래스 객체가 기본 클래스 객체로 전달되는 경우 복사손실 문제가 발생
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Window
{
public :
std::string name() const;
virtual void display() const;
};
class WindowWithScrollBars : public Window
{
public :
virtual void display() const;
};
void printNameAndDisplay(Window w) // 매개변수가 복사손실 당하고 있음
{
std::cout << w.name();
w.display();
}
void main()
{
WidowWithScrollBars wwsb;
printNameAndDisplay(wwsb);
}
|
cs |
결론
결국 위의 모든 내용은 value(값에 의한 복사) reference(값에 의한 참조)입니다.
value 의 경우는 원본데이터를 그대로 복사하는 개념이어서 원본데이터 손실이 없습니다.
단 값을 복사하는 것이라서 크기가 좀 부담스럽게 커져서 성능저하를 일으킬 수가 있습니다.
원본을 그대로 복사하기 때문입니다. 함수 호출시 인자 전달과정에서 발생합니다. 이러한 문제를 해결 할 수 있는 것이 아래의 레퍼런스 입니다.
레퍼런스의 경우에는 값에 의해서 참조하는 개념입니다.
이 경우는 참조되는 원본데이터에 손실이 갈 수가 있습니다.
예로 포인터를 사용하게 되므로 포인터 연산을 하게 될 가능성도 있다는 것입니다.
단 이것은 값에 의한 참조이기 때문에 메모리 크기를 많이 쓰지 않고 성능을 향상 시킬 수 가 있습니다.
그리고 포인터연산에 의해서 원본데이터가 손상된다고 하였는데 그것을 방지하기 위해서 const라는 상수화를 이용하시면 됩니다.
그러면 상수화된 데이터에는 더 이상 접근이 허용되지 않으므로 원본데이터를 손상시키지 않을 수가 있습니다.
가장 중요한 것은 value는 복사의 개념이고 레퍼런스는 참조의 개념입니다.