일반적으로 변수를 상수화시킬 떄 사용하는 예약어로 const키워드를 사용하곤 한다. 그런데, const키워드를 클래스의 멤버함수와 객체에도 사용할 수 있다. 이 경우 어떻게 사용되는지 알아보도록 하자.




1. const 멤버함수

멤버함수에 const를 사용하는 이유는 객체의 멤버변수를 변경시킬 수 없도록 하기 위해서이다.

예를 들어, Get함수의 경우 일반적으로는 private 멤버변수를 반환하는 역할만 하지, 그 멤버변수를 수정하는 일은 절대 없어야 한다.


class Point {

private:

int x_, y_;

public:

Point();

Point(int x, int y);

inline int GetX() const {

return x_;

}

inline int GetY() const {

return y_;

}

}


위와 같이 GetX, GetY 함수는 단순히 private member 변수인 x_, y_의 값을 반환하기만 할 뿐 그 값을 수정하거나 변경하는 일이 없다. 따라서 이러한 함수에는 const키워드를 붙여주는 것이 옳다.


const 키워드가 붙은 const 멤버함수는 객체의 멤버변수를 변경할 수 없는 읽기 전용 함수가 된다. 또한 const 멤버함수는 const로 지정되지 않은 다른 멤버 함수를 호출할 수 없다. 왜냐하면 읽기 전용으로 지정된 const멤버함수에서 const로 지정되지 않은 멤버함수를 호출하게 되면 간접적으로 객체의 멤버변수를 변경시킬수도 있기 때문이다. 


따라서, 앞으로 GetX, GetY와 같은 함수는 const 멤버함수로 선언하는 것이 바람직하다. (그러지 않아도 컴파일 에러는 발생하지 않지만, 코드를 좀 더 견고하고 안전하게 만들기 위해서 필요한 키워드인 것이다.)


참고로 생성자와 소멸자는 const 예약어를 사용할 수 없다. 생성자와 소멸자는 항상 객체의 데이터를 변경시켜야 하기 때문이다.





2. const 객체

멤버변수나 멤버함수 뿐만 아니라 객체에도 const 키워드를 사용할 수 있다. 객체 생성시에 const 키워드를 사용하면, 그 객체는 상수로 취급되어 초기화된 데이터 외의 다른 데이터로 변경할 수 없다. 


const Point pt1(10, 20);

pt1.SetX(30);

pt1.SetY(40);


위와 같은 코드는 컴파일 에러를 발생시킨다. 왜냐하면 SetX, SetY의 멤버함수에서 x_, y_ 멤버 변수값을 변경하려고 하기 때문이다. const키워드가 붙은 객체 인스턴스는 그 멤버변수의 값이 변경되지 않는다.


이러한 논리로 보건대, const 객체는 당연하게도 const 멤버함수만을 제대로 사용할 수 있다. const키워드가 없는 멤버함수는 멤버 변수의 값을 변경할 가능성이 있기 때문에, 호출을 시도하더라도 대부분은 컴파일 에러가 날 것이다.

C++ Programming Inline Function (Working mechanism & Example)


c++언어에서는 인라인 함수라는 것을 제공한다. 인라인이라는 의미는 코드 라인 자체가 안으로 들어간다는 뜻. 즉, 함수의 내용을 호출을 통해서 실행시키는 것이 아니라, 호출하는 코드 자체가 함수 내용의 코드가 되는 효과가 된다는 점이다. 바로 이해한 사람도 있겠지만 아닐 수도 있으니, 예를 들자면...


void PrintHello() {

cout << "Hello, World!" << endl;

}


int main() {

PrintHello();

PrintHello();

return 0;

}


와 같은 코드가 다음과 같이 바뀌게 된다는 뜻이다.


int main() {

cout << "Hello, World!" << endl;

cout << "Hello, World!" << endl;

return 0;

}


눈치챘는가? 인라인 함수는 성능 향상을 위한 것이다. 물론 이렇게 바꿈으로써 실행 코드가 늘어날 수 있다는 단점이 있다. 따라서 인라인 함수는 코드는 작지만(1~3줄 정도) 자주 호출되지 않는 경우에 주로 사용하는 것이 좋다.




| 인라인 함수의 장점


인라인함수는 #define 매크로와 기능이 유사하지만, 인라인 함수만의 장점이 있다.

1. 인라인 함수의 전달인자에 데이터형을 체크할 수 있다. 

(매크로 기능을 활용할 경우에는 파라미터와 리턴값의 데이터 타입을 정확히 '명시'할 수 없게 된다.)

2. 매크로가 갖는 부작용 없이 일반 함수처럼 사용이 가능하다.

(매크로를 사용시에 increment등으로 변수를 넘겨줄 경우 일반적으로 함수를 사용할 때와는 다른 값을 얻게 되는 경우가 많다.)

3. 디버깅이 가능하다. 즉, 현재 변수에 어떤 값이 들어가 있는지 알 수 있다.



| 인라인 함수의 단점


1. 실행 코드가 커진다.

2. 인라인 함수의 구현을 짧게 작성해야 한다. 만약 구현의 내용이 길어진다면 컴파일러는 인라인 함수를 일반 함수로 취급하게 된다.


인라인 함수를 사용함으로써 성능의 향상과 매크로의 부작용을 해결할 수 있다고 하지만, 인라인 함수를 너무 남발하게 되면 실행 코드 자체가 커지게 되는 단점이 있다. 그리고 인라인 함수의 모토는 1~3줄 정도의 짧은 코드를 함수화시킴으로써 효율성의 낭비를 막고자 함이었는데, 코드가 5줄 이상이 되어버린다면 굳이 인라인 함수를 사용할 이유가 없다. 

malloc and realloc functions in C / C++ - Out4Mind

사진 출처: Out4Mind


C언어에는 메모리 할당 및 해제에 대한 4가지 함수가 stdlib.h 라이브러리에서 제공되고 있다.

malloc, calloc, free, 그리고 realloc 함수이다.


이 4가지 함수들 중

realloc 함수의 동작 원리에 대해서 자세히 살펴보고자 한다.


realloc 함수의 프로토타입은 다음과 같다.


void * realloc(void * ptr, size_t size);


realloc 함수는 포인터에 할당된 메모리의 크기를 늘리거나 줄이는 일이 필요할 때 사용하는 함수이다. realloc함수는 호출 시 두 개의 인자를 취하며, 재할당된 영역의 포인터를 반호나한다. 첫 번째 인자는 기존 할당된 메모리에 대한 포인터이며, 두 번째 인자는 요청할 메모리의 크기다. 재할당된 메모리의 크기는 기존 메모리의 크기와 다르며 반환 값은 재할당된 메모리의 포인터다.


 두 개의 인자가 변함에 따라 realloc은 어떻게 작동할까? 아래의 표를 참고하면 한 눈에 이해할 수 있을 것이다.


첫 번째 매개변수 

두 번째 매개변수 

동작 

null 

 임의의 size

 malloc 함수와 동일하다. 

null 아님 

 0

*** 기존 메모리를 해제한다.

null 아님 

 기존 메모리 크기보다 작은 size

 현재 메모리 영역을 사용하여 작은 메모리 영역을 할당한다.

null 아님

 기존 메모리 크기보다 큰 size

 현재 메모리 영역을 사용하거나, 다른 메모리 영역을 사용하여

보다 더 큰 메모리 영역을 할당한다.


+ Recent posts