언어 자료구조 알고리즘/Escort C++

[C++] 특별한 정적 멤버 this

언제나휴일 2016. 4. 15. 13:03
반응형

2.2.5 특별한 정적 멤버 this

 

 모든 클래스에는 컴파일러에 의해 자동으로 캡슐화하는 정적 멤버 this가 있습니다. 멤버 this의 접근 지정은 private으로 설정되어 있어 코드 상에서는 노출되어 있지 않지만, 해당 클래스 스코프 내에서 사용할 수 있습니다. 그리고 this는 해당 클래스 형식의 포인터 형식입니다.

 

 컴파일러는 개체 인스턴스의 멤버 메서드를 호출하면 해당 개체를 this멤버에 설정하고 해당 형식의 메서드를 호출하는 코드로 전개하게 됩니다. 그리고 지역 변수명으로 존재하지 않는 명칭이 멤버 필드에 있으면 자동으로 this 개체의 멤버를 호출하게 코드를 전개해 주게 됩니다. 또한, 개발자가 명시적으로 this 키워드를 통해 멤버 필드에 접근하면 같은 이름의 지역 변수와 구별해서 사용할 수도 있습니다.

 

 C++에서는 전역 변수명과 지역 변수명, 멤버 필드 명이 모두 같더라도 개발자가 원하는 것을 사용할 수 있습니다. 전역 변수를 접근하고 싶으면 ::변수명으로 접근하면 되고 멤버 필드에 접근할 때에는 이미 얘기했던 것처럼 this->멤버 필드명으로 접근, 지역 변수를 접근할 때에는 바로 변수명을 사용합니다.

 

Stu.h

#pragma once

#include <iostream>

#include <string>

using namespace std;

 

class Stu

{

    int num;

    string name;

public:

    Stu(int num,string name);

    ~Stu(void);

    bool IsEqual(int num)const;

    void View()const;

    void Stub();

};

 

 Stu.h에는 멤버 필드로 num name을 캡슐화하였습니다. Stu 생성자 메서드와 IsEqual메서드에서는 this를 통해 지역 변수와 개체 멤버 필드를 구분해서 사용하는 예를 살펴보겠습니다. View 메서드에서는 컴파일러 전개로 실제 호출한 개체의 멤버에 접근하고 있다는 것을 보여 드리고 Stub 메서드에서는 전역 변수와 지역 변수, 개체의 멤버를 구분해서 사용하는 예를 들어 보겠습니다.

 

 생성자 메서드를 보시면 입력 매개 변수명이 멤버 필드명과 같게 들어옵니다. 여기에서는 입력 매개 변수로 들어온 값으로 멤버 필드를 설정해야겠지요. 이 경우에 this 키워드를 통해 멤버 필드에 접근할 수 있습니다. IsEqual 메서드에서도 동일합니다.

 

Stu::Stu(int num,string name)

{

    this->num = num;

    this->name = name;

}

bool Stu::IsEqual(int num)const

{

    return this->num == num;

}

 그리고 View 메서드에서는 지역 변수를 선언하지 않았습니다. 이 경우에 this 키워드를 사용하지 않아도 멤버 필드에 존재하면 this를 통해 멤버 필드에 접근하는 코드로 컴파일러가 전개해 줍니다.

 

void Stu::View()const

{

    cout<<"번호:"<<num<<" 이름:"<<name<<endl;

}

 

 컴파일러에 의해 전개된 코드는 다음과 같습니다.

 

void Stu::View()const

{

    cout<<"번호:"<< this->num<<" 이름:"<< this->name<<endl;

}

 

 만약, 사용하는 곳에서 다음과 같이 사용하면 컴파일러는 사용하는 개체를 해당 클래스의 정적 멤버인 this에 대입을 하고 해당 클래스의 멤버 메서드를 호출하는 코드로 전개해 줍니다

 

Stu *s = new Stu(2,"홍길동");

Stu *s2 = new Stu(3,"강감찬");

 

s->View();

s->View2();

 

컴파일러에 의해 전개된 코드는 다음과 같습니다.

 

Stu *s = new Stu(2,"홍길동");

Stu *s2 = new Stu(3,"강감찬");

 

Stu:: this = s;

Stu::View();

Stu:: this = s2

Stu::View2();

 

 이와 같은 컴파일러 전개 과정이 있기 때문에 정확하게 호출할 때 사용한 멤버 필드를 사용할 수 있는 것입니다. 눈치를 채신 분도 있겠지만 this 멤버의 접근 설정이 private으로 지정되어 있어 다른 스코프에서 접근할 수 없다고 했는데 이는 가시성을 없게 하여 개발자로 하여금 잘못된 접근을 막는 것일 뿐입니다. 컴파일러의 무소불위의 권한으로 이처럼 전개가 이루어진다는 것이지 실제 개발자가 위와 같은 코드를 작성하면 컴파일 오류가 발생합니다.


 마지막으로 Stub 메서드의 사용 예를 살펴보면 다음과 같습니다. 이 예에서는 전역 변수명과 지역 변수명, 멤버 필드 명이 같을 때 각각에 대해 어떻게 접근할 수 있는가에 대해서 보여주기 위한 예입니다.

 

int num=10;

void Stu::Stub()

{

    int num = 3;

    this->num = 8;

    ::num = 9;

    num = 7;

    cout<<"지역 변수 num:"<<num<<endl;

    cout<<"전역 변수 num:"<<::num<<endl;

    cout<<"개체 멤버 num:"<<this->num<<endl;

}

 

 예를 보면 전역 변수로 num이라는 변수가 선언되어 있고 지역 변수에도 num이 선언되어 있습니다. 그리고 앞선 Stu.h를 보시면 멤버 필드 num도 캡슐화되어 있습니다. C++언어에서는 이 같은 경우에도 스코프 연산자와 this 키워드를 통해 전역 변수와 멤버 필드에 접근할 수 있게 해 주고 있습니다. 그리고 아무것도 사용하지 않을 때에는 해당 명칭이 지역 변수에 있다면 지역 변수를 사용하는 것이 되고 지역 변수에 없고 멤버 필드에 있으면 멤버 필드가 사용되고 지역 변수와 멤버 필드에 없는데 전역 변수로 선언되어 있다면 전역 변수가 사용됩니다.

 

Stu *s = new Stu(2,"홍길동");

s->Stub();

 

 위와 같이 사용을 하면 [그림 2.11]과 같은 결과를 얻게 됩니다.


C++에서 지역 변수, 전역 변수, 멤버 변수 접근

[그림 2.11]

 

Stu.cpp

#include "Stu.h"

 

Stu::Stu(int num,string name)

{

    this->num = num;

    this->name = name;

}

Stu::~Stu(void)

{

}

 

bool Stu::IsEqual(int num)const

{

    return this->num == num;

}

void Stu::View()const

{

    cout<<"번호:"<<num<<" 이름:"<<name<<endl;

}

int num=10;

void Stu::Stub()

{

    int num = 3;

 

    this->num = 8;

    ::num = 9;

    num = 7;

 

    cout<<"지역 변수 num:"<<num<<endl;

    cout<<"전역 변수 num:"<<::num<<endl;

    cout<<"개체 멤버 num:"<<this->num<<endl;

}

  

Exmaple.cpp

#include "Stu.h"

 

void main()

{

    Stu *s = new Stu(2,"홍길동");

    Stu *s2 = new Stu(3,"강감찬");

 

    if(s->IsEqual(2))

    {

        cout<<"같다."<<endl;

    }

    else

    {

        cout<<"다르다."<<endl;

    }

 

    s->View();

    s2->View();

    delete s;

    delete s2;

}

 

위의 예를 수행하면 [그림 2.12]와 같은 결과를 얻게 됩니다.


[그림 2.12]


2장 캡슐화 Part1 

2장 캡슐화 Part2 

(모든 동영상 강의는 무료입니다.)

반응형