Coding Memo

[메모] const 함수 유의사항 (C2665 에러 등) 본문

Language/C++

[메모] const 함수 유의사항 (C2665 에러 등)

minttea25 2024. 4. 16. 15:04

에러

 

Lock을 이용한 Queue를 만들고 컴파일 중에 발생했다.

일단 에러 내용은 이러하다.


상황

 

단순히 보면 ReadLock이라는 함수의 인자가 일치하지 않아서 나타나는 문제로 보인다...

 

bool TryPeek(T& top) const
{
	ReadLock __r_lock(_lock); // 문제의 코드

	if (_queue.empty()) return false;
	else
	{
		top = _queue.top();
		return true;
	}
}

 

문제가 되는 함수이다.

간단히 설명하면, queue에서 peek을 하기위해 readlock을 걸어두고 queue를 읽는다.

 

class ReadLock
{
public:
	ReadLock(Lock& lock) : _lock(lock) { _lock.ReadLock(); }
	~ReadLock() { _lock.ReadUnlock(); }
private:
	Lock& _lock;
};

 

ReadLock 클래스는 위와 같다.

추가적으로, Lock::ReadLock은 내부적으로 lockFlag를 변경하여 해당 스레드가 read중임을 나타내는 함수이다.

 

딱히 문제가 없어 보인다. ReadLock의 생성자에 대해 _lock을 지정하여 제대로 코드를 작성한 것으로 보인다. 그러나 에러 내용으로 볼 때는 ReadLock 생성 과정에서 인수가 일치하지 않은 함수가 있다는 것 같다.

 

?????

 


해결

 

오류 디테일을 확인해서, 왜 `인자 불일치`라는 에러가 나타났는지 알 수 있었다.

 

좀 더 풀어서 보면,

 

1. `TryPeek()` 함수가 `const`로 선언되었기 때문에, 해당 함수 내에서는 클래스의 멤버 변수를 변경 할 수 없다.

2. 마찬가지로 `TryPeek()`에서는 const 함수만 호출이 가능하다.

2. `ReadLock`의 클래스 생성자에서 `_lock.ReadLock()`이 호출되는데, 이 함수에서 _lock의 상태를 변경하고 있다.

3. 즉, `Lock::ReadLock()`은 const 함수가 될 수 없고 `ReadLock`생성자 또한 const 함수가 될 수 없다. 따라서 이 함수들은 const 함수인 `TryPeek()`에서 호출될 수 없다.

4. 컴파일러는 const 함수인 ReadLock의 생성자를 찾으려고 할 것이다. 그러나 const인 생성자를 찾을 수 없다.

5. `const ReadLock(Lock& lock)` 을 찾을 수 없기 때문에, 인자 불일치라는 컴파일 에러가 나타난다.

 

const를 제거해서 간단하게 해결할 수 있는 문제였다.


결론

 

1. 오류를 확인할 때는 이유를 잘 모르겠다면, 상세한 오류 내용을 확인하자.

2. const 함수는 내부에서 해당 객체의 상태변경을 제한하고, 내부에서 다시 호출되는 코드에서도 마찬가지이다. 사용할 때는 이에 유의하자.