헤더파일

C++ 상수 멤버 함수 operator new 재정의 본문

C++

C++ 상수 멤버 함수 operator new 재정의

헤더파일 2020. 3. 11. 14:04

상수 멤버 함수를 코드의 실수를 줄이는 이유도 있지만 상수 객체에서 사용하기 위한 이유도 있습니다.

 

class Rect
{
	int width;
	int height;

public:
	Rect(int x, int y) :width(x), height(y) {}

	int getArea()/*const*/ { return width * height; };
};


void foo(const Rect& r)
{
	cout << r.getArea(); // Error
}


int main()
{
	Rect r(10, 20);
	foo(r);
}

위와 같이 foo에서 객체를 받을 때 const 참조 형태로 받는 것은 일반적인 상태입니다. 하지만 r은 상수 객체이므로 const가 아닌 멤버함수를 호출하면 컴파일 에러가 발생합니다. 따라서 값을 변경하지 않는 모든 멤버함수는 뒤에 const를 붙이는게 좋습니다.

 


만약에 상수 맴버함수에서 꼭 바꿔야 하는 변수가 있다면 두 가지 해결책이 있습니다.

 

1. 변수 앞에 mutable로 선언한다.

 

2. 변수를 힙에 할당하여 사용한다.

 

//mutable bool check;
//bool* check;


int getArea() const { 

  if (!check) //if(!*check)
  check = true;// Error//*check = true;

  return width * height;
};

 

 


operator new, operator delete 재정의

 

class Test
{
public:
	Test() { cout << "생성자" << endl; }
	~Test() { cout << "소멸자" << endl; }
};


void* operator new(size_t sz)
{
	cout << "new!" << endl;
	return malloc(sz);
}

void* operator new(size_t sz, int id)
{
	cout << "new!" << id << endl;
	return malloc(sz);
}


void operator delete(void* p) noexcept
{
	free(p);
}

int main()
{
	Test* t = new Test();
	Test* t2 = new(123) Test();
}

//출력
new!
생성자
new!123
생성자

operator new와 delete를 재정의 하면 new를 이용해 객체를 할당할때 불리는 함수를 사용자가 만들 수 있습니다. new, delete의 모든 기능은 아니고 메모리 할당 부분에 대해서만 가능합니다. 인자를 받는 new 를 만들어 오버로딩도 가능합니다. 이후에는 new의 원래 동작에 따라 생성자와 소멸자가 호출됩니다.

 

 

new 는 객체를 생성하는 함수입니다. 

 

1. 메모리를 할당한다.

2. 생성자를 호출한다.

3. 객체타입으로 포인터를 변환한다.

 

따라서 아래와 같은 표현은 다음과 같이 이해할 수 있습니다.

 

void* operator new(size_t sz, void* p)
{
	return p;
}

int main()
{
	Test* t = new Test(); // 새로운 메모리에 객체를 생성해 달라

	new(t) Test;//이미 객체가 있는 메모리에 생성자를 호출해 달라
}

 위의 operator new 오버로딩은 이미 c++에서 정의되어 있습니다. void*를 전달하는 new 를 사용하게 되면 메모리할당 없이 생성자만 명시적으로 호출할 수 있습니다.

 

 

 

'C++' 카테고리의 다른 글

c++ Trivial  (2) 2020.03.19
C++ name mangling  (0) 2020.03.11
C++ 멤버함수  (0) 2020.03.09
캐스팅 정리  (0) 2019.11.17
스레드 프로그래밍  (0) 2019.11.06
Comments