c++ call by reference에 대해

kjw9122의 이미지

class person {
private:
	int age;
public:
	person(int age) {
		this->age = age;
	}
	int getAge() {
		return age;
	}
};
 
void main() {
	person* a = new person(20);
	person* b = new person(10);
 
	cout << "before : " << a->getAge() << b->getAge() << endl;
	swap(a, b);
	cout << "after : " << a->getAge() << b->getAge() << endl;
}
 
void swap(person* c, person* d) {
	person* temp = c;
	c = d;
	d = temp;
}

결과값
before : 2010
after : 1020

위와 같은 소스코드에서요. 결과값을 보면 위와같이 의도한데로 swap 함수가 제대로 동작합니다.
근데 main에서 person 포인터변수 a와 b가 가리키고 있는 객체의 주소를 swap함수를 호출할 때 매개변수로 넘겨주고
swap과정을 거치게 되면 swap함수 내부에 있는 지역변수인 c, d 사이에서만 객체의 주소값이 바뀌고
swap함수가 종료되고 다시 main으로 돌아오면 main의 지역변수 a, b는 그대로 원래의 주소값을 지니고 있어야 하는거 아닌가요?
결과를 보게되면 swap함수 내부 지역변수 사이에서 주소값이 바뀐게 main의 지역변수 a,b에도 영향을 주는데
이게 왜 swap이 되는지 이해가 안되네요.

gilgil의 이미지

> 결과를 보게되면 swap함수 내부 지역변수 사이에서 주소값이 바뀐게 main의 지역변수 a,b에도 영향을 주는데
swap 함수가 호출이 되고 나면 main에서 a, b의 주소값이 바뀌는 게 아니고 내용이 바뀌는 겁니다.

kjw9122의 이미지

main 함수에서 포인터 a,b 출력해본 결과로는 주소값이 바뀌네요.
before : 20, 10
before : 00A3D318, 00A381C0
after : 10, 20
after : 00A381C0, 00A3D318
또한 말씀해주신데로 값이 바뀌는것 역시 swap에서 temp = c, c = d, d = temp 모두 주소값에 대한 대입이 이루어지는데.. 논리적으로 이해가안되네요.

jick의 이미지

main 앞에 swap이 선언이 안 되어 있나요? 왠지 main에서 저 코드의 swap을 부르는 게 아니라 std::swap을 부르고 있는 게 아닌가 싶은데요.

swap 함수 안에 "swap 불렸음!"이라고 출력하는 코드를 넣은 다음에 정말로 불리는지 확인해 보세요.

gilgil의 이미지

에구, 에구 그렇네요. 제가 코드를 잘못 해석한 듯.
swap function이 forward declaration이 안되어 있으면 컴파일러는 move.h 안에 있는 template function을 이용하는군요.

ps: 영훈이 잘 지내남? 새해 복 많이 받아라. ^^

HDNua의 이미지

1. 참고로 지금 구현하신 swap에는 문제가 있습니다.

void swap(person* c, person* d) {
	person* temp = c;
	c = d;
	d = temp;
}

이렇게 구현하시면 지역 변수인 c, d, temp의 값만 바뀌고 main 쪽의 지역 변수인 a, b의 값은 전혀 바뀌지 않습니다.
인자에 &를 붙여 reference를 만들거나, double pointer를 사용하시고 * 연산자를 사용하셔야 합니다.

저는 이렇게 생각했습니다.

twinwings의 이미지

HDNua 님이 정답인 것 같구요. swap은 왠만하면 std::swap 이용하는게 좋습니다.

예외인 경우는 객체가 imple patern pimple patern으로 구현됐을때 정도...겠지요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.