C++ this 사용법 - C++ this sayongbeob

클래스(class)는 객체 지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메서드를 정의하는 일종의 틀이며 내부적으로 객체를 정의하기 위한 상태 값을 의미하는 멤버 변수와 클래스의 동작인 메서드(함수)로 구성됩니다. 객체 지향 프로그래밍에서는 모든 데이터를 객체(object)로 취급하며 이 객체들의 조합으로 프로그래밍을 하는 방식을 의미합니다. C++에서 클래스(class)란 구조체(struct)의 상위 호환으로 이해할 수 있습니다. 구조체와 다른점은 접근 제어 지시자가 추가되었고 함수를 포함할 수 있게 된 점입니다.

 

접근 제어 지시자

지시자설명public어디서든 접근이 가능 (외부에서도 모두 접근 가능)private클래스 내부에 정의된 함수에서만 접근 허용 (중요한 정보를 감출때 사용)protected기본적으로는 private이지만 상속관계에 놓여있을 때, 유도 클래스에서는 접근 허용

 

 클래스(Class) 사용법 

클래스 생성

class 클래스 이름{ 접근 제어 지시자: 멤버변수: 멤버함수 };

C++에서는 클래스를 위와 같은 문법으로 생성합니다.

class MyCar { private: //멤버변수 int fuel = 0; bool power = false; public: //메소드 void go() { this->fuel--; } void oiling(int n) { this->fuel += n; } void fuel_check() { std::cout << "연료 : " << fuel << std::endl; } };

예를 들자면 위와 같습니다. 여기서 this는 클래스 내의 멤버 변수를 의미합니다. this포인터는 클래스의 실제 인스턴스에 대한 주소를 가리키는 포인터로써 사용해주면 멤버 변수와 같은 이름의 인자값이 들어와도 멤버 변수와 인자 값을 구분 지어질 수 있고 this로 가리키는 변수가 클래스의 멤버 변수라는 것이라는 직관성이 높아집니다.

 

클래스 생성 및 사용

MyCar car = MyCar(); //생성 //메서드 호출 car.oiling(100); car.fuel_check(); for (int i = 0; i < 10; i++) car.go(); car.fuel_check(); car.oiling(100); for (int i = 0; i < 10; i++) car.go(); car.fuel_check();

클래스의 생성과 사용은 위와 같이 하시면 됩니다.

 

클래스 배열 사용

MyCar car[3]; //생성 for (int i = 0; i < 3; i++)car[i] = MyCar(); //초기화 //메서드 호출 car[0].oiling(100); car[0].fuel_check(); for (int i = 0; i < 10; i++) car[0].go(); car[0].fuel_check();

클래스 배열을 사용할때는 생성 즉시 바로 초기화가 안됩니다. 생성 후 따로 for문을 돌려서 일일이 초기화를 시켜준 뒤 사용하셔야 합니다. 클래스 배열이 생성 후 즉시 초기화가 안되므로 기본 생성자가 클래스 내부에 정의되어 있어야 사용이 가능합니다.

 

생성자와 소멸자

생성자와 소멸자는 클래스 객체가 생성 및 소멸될 때 자동으로 호출되는 함수입니다. 생성자 소멸자의 경우 따로 기술하지 않아도 컴파일러가 알아서 만들어서 넣습니다. 단 이렇게 생성된 생성자, 소멸자는 아무런 기능이 없습니다. 반대로 아래와 같이 따로 프로그래머가 만들어줄 수도 있습니다.

class MyCar { private: //멤버변수 int fuel = 0; bool power = false; public: //생성자 MyCar() { this->fuel = 100; this->power = true; } //생성자 다중 정의 MyCar(int n) { this->fuel = n; this->power = true; } //소멸자(다중 정의 불가능) ~MyCar() { std::cout << "소멸되었습니다." << std::endl; } };

이 두함수의 가장 큰 특징은 함수임에도 불구하고 반환 형식이 없다는 것과 함수 이름이 클래스 이름과 같다는 점입니다. 다만 소멸자의 경우 앞에 ~가 붙습니다. 생성자는 오버로딩을 통한 다중 정의가 가능하고 소멸자의 경우에는 다중 생성이 불가능합니다. 생성자는 객체를 생성할때 호출되고 소멸자는 객체가 생성된 블록이 끝날때 소멸자를 호출 합니다. 생성자와 소멸자 이외에도 객체를 복사할 때 사용되는 복사 생성자, 복사 대입 연산자도 있습니다. 이 또한 생략하면 컴파일러가 자동으로 넣어줍니다. 복사 생성자와 복사 대입 연산자가 궁금하시다면 아래 글을 참고해주세요.

this 포인터

멤버 함수의 공유

C++에서 하나의 클래스에서 생성된 인스턴스는 각각 독립된 메모리 공간에 저장된 자신만의 멤버 변수를 가지지만, 멤버 함수는 모든 인스턴스가 공유합니다.

따라서 Book 클래스를 이용해 두 개의 인스턴스를 생성해도, TickerBook()이라는 멤버 함수는 하나만이 존재합니다.

즉, 더 두꺼운 책의 이름을 출력해 주는 TickerBook() 멤버 함수는 두 인스턴스가 같이 공유하게 됩니다.

ThickerBook() 멤버 함수의 정의는 다음과 같습니다.

정의

const Book& Book::ThickerBook(const Book& comp_book)

{

    if (comp_book.total_page_ > total_page_)

    {

        return comp_book;

    }

    else

    {

        return ???; // 자신을 호출한 인스턴스를 반환하는데 알 수가 없음.

    }

}

그리고 ThickerBook() 멤버 함수는 다음과 같이 호출될 것입니다.

예제

web_book.ThickerBook(html_book);

이때 ThickerBook() 멤버 함수는 자신을 호출한 객체가 web_book 객체임을 인수를 통해 전달받아야만 합니다.

그래야만 else 문에서의 반환값을 정확히 명시할 수 있기 때문입니다.

this 포인터

위와 같은 이유로 C++에서는 모든 멤버 함수가 자신만의 this 포인터를 가지고 있습니다.

이 this 포인터는 해당 멤버 함수를 호출한 객체를 가리키게 되며, 호출된 멤버 함수의 숨은 인수로 전달됩니다.

이렇게 하면 호출된 멤버 함수는 자신을 호출한 객체가 무엇인지 정확히 파악할 수 있습니다.

this 포인터를 사용하여 위의 ThickerBook() 멤버 함수를 다시 정의하면 다음과 같습니다.

정의

const Book& Book::ThickerBook(const Book& comp_book)

{

    if (comp_book.total_page_ > total_page_)

    {

        return comp_book;

    }

    else

    {

        return *this; // 자신을 호출한 인스턴스를 반환함.

    }

}

this는 포인터이므로, 반환할 때에는 참조 연산자(*)를 사용하여 호출한 객체 그 자체를 반환해야 합니다.

예제

int main(void)

{

    Book web_book("HTML과 CSS", 350);

    Book html_book("HTML 레퍼런스", 200);

    cout << web_book.ThickerBook(html_book).title_; // 더 두꺼운 책의 이름을 출력함.

    return 0;

}

Book::Book(const string& title, int total_page)

{

    title_ = title;

    total_page_ = total_page;

    current_page_ = 0;

    set_percent();

}

void Book::set_percent() { percent_ = (double) current_page_ / total_page_ * 100; }

const Book& Book::ThickerBook(const Book& comp_book)

{

    if (comp_book.total_page_ > this->total_page_)

    {

        return comp_book;

    }

    else

    {

        return *this;

    }

}

코딩연습 ▶

this 포인터는 암시적으로도 사용될 수 있지만, 가급적 화살표(->) 연산자를 통해 명시적으로 사용하는 것이 좋습니다.

this 포인터의 특징

C++에서 this 포인터는 다음과 같은 특징을 가집니다.

1. this 포인터는 클래스, 구조체 또는 열거체 타입의 비정적 멤버 함수에서만 사용할 수 있습니다.

2. 정적(static) 멤버 함수는 this 포인터를 가지지 않습니다.

3. this 포인터는 언제나 포인터 상수이며, 따라서 값을 재할당할 수 없습니다.

C++ 정적 멤버 함수에 대한 더 자세한 사항은 C++ 정적 멤버와 상수 멤버 수업에서 확인할 수 있습니다.

C++ 정적 멤버와 상수 멤버 수업 확인 =>

연습문제

Toplist

최신 우편물

태그