C++에서 기본적인 포인터 관련해서 질문 드립니다..

wildwar의 이미지

class A {
public : 
	A() {
		setName("AA");
	};
	void setName(string a) {
		name = a;
	};
	string get() { return name; };
private:
	string name;
};
 
class B : public A
{
public :
	B() : A() { setName("BB"); };
};
 
void func(A* cla)
{
	cout << cla << endl; // 2번
	cla = new B();
 
	cout << cla << endl; // 3번
}
 
int main()
{
	A * aaaa = new A();
 
	cout << aaaa << endl; // 1번
 
	func(aaaa);
	cout << aaaa << endl; // 4번
 
 
}

코드는 위와 같고,

출력시에는
1, 2, 4번은 동일한 주소, 3번은 다른 주소가 나옵니다.

메모리 관점에서 좋지 않은 코드인건 알지만 실행시켰을 때 제 생각과 다른 결과가 나와서 질문드립니다.

저는 위 코드에서 func 함수로 넘어 갈 때 포인터형 객체를 넘겨주기 때문에

func함수내의 ' cla = new B(); ' 구문에서 새로운 주소값을 할당하고 리턴이 되어도

메인에서 새로운 주소값이 지정되어 있어야 한다고 생각했습니다.

그래서 마지막에 결과가 제 생각과 다르게 나오는 이유를 아무리 생각해도 모르겠는데... 답변주시면 정말 감사하겠습니다.

( 비쥬얼 스튜디오로 작성하였습니다. )

 의 이미지

1. 포인터 변수도 변수입니다.
값이 있고, 주소가 있으며, (참조자로 받지 않는 한) 함수 매개변수에 넣으면 그 값이 전달됩니다.
일반적인 포인터 변수의 주소를 다루는 포인터를 이중 포인터라고 합니다.
물론 삼중 포인터, 사중 포인터 등도 있을 수 있죠.

void example1(void){
    int variable;
    int *pointer_1 = &variable;
    int **pointer_2 = &pointer_1;
    int ***pointer_3 = &pointer_2;
    int ****pointer_4 = &pointer_3;
}

일반적으로 이중 포인터 정도만 되어도 직관의 영역을 아슬아슬하게 벗어나기 쉬워서 항상 주의를 요합니다.
지금 어떤 타입의 포인터를 쓰고 있으며 무엇을 가리키고 있는지 정확히 알고 있어야 하지요.

2. 질문으로 돌아가서, func함수는 main함수의 포인터 변수 aaaa의 을 바꿀 수 없습니다.
그 변수의 주소를 받은 게 아니라 값을 받았기 때문이죠. A *int로 치환하면 아래와 같이 짠 것과 똑같아요.

void func(int cla)
{
    cout << cla << endl; // 2번
    cla = 1;
    cout << cla << endl; // 3번
}
 
int main()
{
    int aaaa = 0;
    cout << aaaa << endl; // 1번
    func(aaaa);
    cout << aaaa << endl; // 4번
}

위 코드에서는 3번만 다른 값(1)을 갖는 게 분명하죠. 질문자님의 코드도 마찬가지입니다.
func에서 main의 aaaa 변수의 값을 바꾸기 위해서는 aaaa의 타입(int)에 대한 포인터(int *) 매개변수로 받아야겠죠.

질문자님의 코드도 마찬가지입니다. aaaa의 타입(A *)에 대한 포인터 (A **) 매개변수로 받아야 합니다.

void func(A **cla)
{
    cout << *cla << endl; // 2번
    *cla = new B();
    cout << *cla << endl; // 3번
}
 
int main()
{
    A *aaaa = new A();
    cout << aaaa << endl; // 1번
    func(&aaaa);
    cout << aaaa << endl; // 4번
}

여기저기 추가되는 &와 *를 줄이고 싶다면, 음, 혹시 참조자 배우셨나요?

void func(A *&cla)
{
    cout << cla << endl; // 2번
    cla = new B();
    cout << cla << endl; // 3번
}
 
int main()
{
    A *aaaa = new A();
    cout << aaaa << endl; // 1번
    func(aaaa);
    cout << aaaa << endl; // 4번
}

wildwar의 이미지

와... 코드까지 적어가며 친절하게 알려주시다니 너무 감사합니다..
포인터에 대해 제대로 이해하고 있다고 생각했는데 전혀 아니었네요,,,
덕분에 좋은 지식 얻어갑니다!
정말 감사합니다!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.