2021 시작

기본적으로 C++는 함수에 객체를 전달할 때 C와 똑같이 값에 의한 전달을 사용한다. 특별히 따러 지정해주지 않은 한은 "사본"을 쓴다는 것이다. 하지만 여기서 "사본"을 쓸 때 문제가 생긴다. 첫 번째로는 연산을 쓸 때 없이 증가시킬 수도 있다는 것이다. 다음 코드를 봐보자

class Person 
{
private:
	string name;
	string address;

public:
	Person() {}			
	virtual ~Person() {}
};

class Student : public Person 
{
private:
	string schoolName;
	string schoolAddress;

public:
	Student() {}
	~Student() {}
};

bool validateStudent(Student s);	//Student를 값으로 전달받는 함수

Student plato;					

int _tmain() 
{
	bool platoIsOK = validateStudent(plato);//함수 호출

}

valilateStudent 함수를 값에 의한 전달을 이용하여 함수호출 시 각 각 6번의 생성자와 소멸자의 호출이 쓸 때 없이 이뤄졌다.(name,address,person,schoolname,schooladdress,student)소멸자도 똑같다.

왜 이렇게 되냐면은 아까 말했듯이 "사본"을 쓴다고 했다. 그렇다면 함수의 매개변수에 넘겨진 객체와 똑같은 값을 가진 "또 다른" 객체가 새로 만들어지는 것이다. 그러기에 당연하게도 기본 클래스와 상속클래스, 그리고 그 안에 있는 객체들까지 해서 생성자가 6번 일어나는 것이다.(클래스를 사용하려면 그 해당 클래스 객체는 반드시"생성자"를 이용하여 초기화를 해야 한다는 것을 잊지 말자.) 이 쓸모없는 연산 행위를 해결할 수 있는 간단한 방법이 있다. 참조자를 쓰는 것이다. 

bool validateStudent(const Student& s);

이렇게 하면 위와같은 쓸데없는 연산 행위도 막을 수 있고 또 한 가지의 문제점을 막을 수 있다. 그 문제점이란 복사 손실 문제이다. 다음 코드를 봐보자

class TEST 
{
public:

	virtual void ClassFunc() const
	{
		cout << "Test" << endl;
	}
};

class SubTest : public TEST
{
public:

	virtual void ClassFunc() const
	{
		cout<<"Test2"<<endl;
	}

};

void TestFunc(TEST t) //밑에 TEST2부분이 잘려나감
{
	t.ClassFunc();
}

int main() 
{
	SubTest t;
	TestFunc(t);		//문제 발생!
}

위 코드에서 TestFunc 함수를 호출하면 복사손실문제가 발생한다. SubTest부분이 날라가버린다는것이다. 그 증거로 virtual 함수인 ClassFunc함수를 호출하면 SubTest의 ClassFunc함수가 아닌 TEST의 TestFunc함수가 호출된다.

하지만 이것도 아까 말했듯이 &참조자를 붙여주는것으로 해결할 수 있다.

 

 

이것만은 잊지 말자!

 

1."값에 의한 전달" 보다는 "상수 객체 참조자에 의한 전달"을 선호한다. 대체적으로 효율적일뿐만 아니라 복사손실 문제까지 막아준다.

2. 이번 항목에서 다룬 법칙은 기본제공 타입 및 STL 반복자, 그리고 함수 객체 타입에는 맞지 않는다.. 이들에 대해서는 "값에 의한 전달"이 더 적절하다.

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading