1. 상수 멤버 함수 (const member function)
#include <iostream>
class Point {
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
void set(int a, int b) { x = a; y = b; }
void print() const {
x = 10;
std::cout << x << ", " << y << std::endl;
}
};
int main() {
}
① 상수 멤버 함수 (const member function)
=> 함수 언어 및 구현시 함수 괄호 뒤에 const가 붙는 함수
=> void print() const
② 상수 멤버 함수의 특징
=> 상수 멤버 함수 안에서는 모든 멤버를 상수 취급한다.
=> 멤버 데이터의 값을 읽을 수는 있지만 변경할 수는 없다.
③ 상수 멤버 함수를 사용하는 이유 - 중요!
=> 코드 작성시 안정성
=> 상수 객체는 상수 멤버 함수만 호출할 수 있다.
2. 상수 멤버 함수가 필요한 이유
#include <iostream>
class Point {
public:
int x, y;
Point(int a = 0, int b = 0) : x(a), y(b) {}
void set(int a, int b) { x = a; y = b; }
void print() {
x = 10;
std::cout << x << ", " << y << std::endl;
}
};
int main() {
const Point pt(1, 1); // 상수 객체
pt.x = 10; // error
pt.set(10, 10); // error
pt.print(); // ? - error
}
위의 코드에서 pt라는 상수객체로 만들었다.
pt는 상수객체이기 때문에 x에 접근하여 값을 바꿀수도, set 멤버함수를 통해 값을 바꿀수도 없다.
하지만 값을 출력할 뿐인 print함수는 어떨까?
결과는 error가 난다.
이유는 컴파일러가 컴파일 할때 함수명만을 보고 컴파일하게 되는데
내용을 보지 않고 값을 바꾸는지 바꾸지 않는지 알 수 없기 때문에 에러를 뱉는다.
① 핵심
=> 상수 객체는 상수 멤버 함수만 호출 할 수 있다.
② const Point pt(1, 1);
=> 상수 객체이므로 객체의 상태를 변경할 수 없어야 한다.
=> 하지만 상태를 얻거나 출력 할수는 있어야 한다.
=> print 멤버 함수는 반드시 상수 멤버 함수로 해야 한다.
class Rect {
int xpos, ypos, width, height;
public:
Rect(int x = 0, int y = 0, int w = 0, int h = 0)
: xpos(x), ypos(y), width(w), height(h) {}
int getArea() const { return width * height; }
};
// void tmp(Rect r) {
void tmp(const Rect& r) {
int n = r.getArea();
}
int main() {
Rect r(1, 1, 10, 10); // 비 상수 객체
int n = r.getArea();
tmp(r);
}
③ 사용자 정의 타입을 함수로 전달할 때
=> call by value보다는 const reference가 좋다.
④ const reference로 전달 받는 경우 상수 객체이다.
=> 상수 객체라도 객체의 상태를 읽을 수는 있어야 한다.
⑤ 객체의 상태를 변경하지 않는 모든 멤버 함수는 반드시 상수 멤버 함수로 만들어야 한다.
3. 상수 멤버 함수 관련 문법 정리
#include <iostream>
class Point {
int x, y;
mutable int cnt = 0;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
void print() const {
++cnt;
std::cout << x << ", " << y << std::endl;
}
};
int main() {
Point pt(1, 1);
pt.print();
pt.print();
}
위의 코드에서 print함수가 몇 번이나 호출되었는지 알고 싶다라면
count변수를 추가하고 print에서 count를 증가시키면 된다.
그런데 print는 상수 멤버 함수라 안에서 값을 변경할 수 없다.
이럴 땐 어떡해야 할까?
① mutable 멤버 데이터
=> 상수 멤버 함수 안에서도 값을 변경할 수 있다.
class Test {
public:
void tmp() {} // 1
void tmp() const {} // 2
};
int main() {
Test 1;
t1.tmp(); // 비 상수 객체 1번 호출
// 만약 없다면 2번 호출
const Test t2;
t2.tmp(); // 상수 객체 2번 호출
// 만약 없다면 error
}
② 동일 이름의 상수 멤버 함수와 비 상수 멤버 함수를 만들 수 있다.
class Test {
int data;
public:
// int* getDate() const { return &data; } // data는 상수이다.
const int* getDatea() const { return &data; }
};
int main() {
}
③ 상수 멤버 함수 안에서 모든 멤버는 const이다.
④ 함수를 선언과 구현으로 분리할 때는 선언과 구현 모두에 const를 표기해야 한다.
=> 컴파일시 헤더파일과 main을 본다.
'프로그래밍 > C++' 카테고리의 다른 글
[C++] 상속 (0) | 2019.11.24 |
---|---|
[C++] this 포인터 (0) | 2019.11.24 |
[C++] static member function (0) | 2019.11.17 |
[C++] static member data (0) | 2019.11.14 |
[C++] 객체의 복사 방법 (0) | 2019.11.13 |