멤버 함수 이름 탐색

J·2025년 12월 21일
  • 함수는 자신이 속한 유효 범위를 가짐
    • 전역 함수 => 전체
    • 멤버 함수 => 해당 클래스
    • 부모 클래스와 자식 클래스가 있을 경우, 부모 클래스의 유효 범위는 자식 클래스의 유효 범위를 포함한다.
      • 즉, 상속 관계에서 이름 탐색은 [최종 클래스 -> 조상 클래스 -> 전역] 의 형태이다. (파생 클래스에서 같은 이름의 함수를 하나라도 선언하면 기반 클래스의 함수는 가려짐)

일반적인 경우

class CParent
{
	public:
    	void Func1(){}
};

class CChild : public CParent
{
	public:
    	void Func2(){}
};

void main()
{
	CChild c;
    c.Func1();
    c.Func2();
    c.Func3(); // 컴파일 에러!!
}

탐색 유효 범위 및 순서는 다음과 같다.

이름이 가려지는 경우

class CParent
{
public:
	void Func() {}
};

class CChild :public CParent
{
public:
	void Func(int arg) {}
};

void main()
{
	CChild c;

	c.Func(1);
	// c.Func(); // 컴파일 에러 
}

탐색 범위는 다음과 같다.

컴파일러는 최초 탐색 범위인 ① CChild에서 Func를 찾아냈지만, 인자의 개수가 맞지 않기 때문에 컴파일 에러를 발생시킨다.

다음의 경우도 마찬가지이다.


class CParent
{
public:	
	void Func() { printf("CParent Func()\n"); }
	void Func(double) { printf("CParent Func(double)\n"); }
	virtual void VFunc() { printf("CParent VFunc()\n"); }
	virtual void VFunc(int) { printf("CParent VFunc(int)\n"); }
};

class CChild : public CParent
{
public:
	void Func(int a) 
	{
		printf("CChild Func(int)\n");
	}
	void VFunc() override { printf("CChild VFunc()\n"); }
};

int main()
{
	CChild c;

	//c.VFunc(1); // 컴파일 에러 발생!!
	//c.Func(); // 컴파일 에러 발생!!

	c.Func(2.5); // CChild::Func(int)가 호출된다.
	c.VFunc();

}

내가 생각한 탐색의 범위 및 순서는 다음과 같다.

컴파일러는 이미 CChild에 대해 Func(int)와 VFunc()을 탐색하였기 때문에 CParent의 함수는 탐색하지 않는다.

결과
그렇기 때문에 CParent의 함수들은 가려졌고, 실행할 시 컴파일 에러가 발생한다.

해결

부모의 함수 이름이 가려지는 문제의 해결 방법

방법 1. 실행 시 명시적으로 부모의 함수를 호출하도록 한다.
방법 2. using을 통해 CChild의 범위에서 부모의 함수들까지 탐색할 수 있도록 이름을 넣어준다.

방법 1 (스코프를 통해 명시적 사용)

int main()
{
	// 방법 1

	CChild c;

	c.CParent::VFunc(1); 
	c.CParent::Func(); 
	c.CParent::Func(2.5); // CParent::Func(double)이 호출된다.

	c.Func(2.5); // CChild::Func(int)가 호출된다.
	c.VFunc();

}

결과

방법 2
class CParent
{
public:	
	void Func() { printf("CParent Func()\n"); }
	void Func(double) { printf("CParent Func(double)\n"); }
	virtual void VFunc() { printf("CParent VFunc()\n"); }
	virtual void VFunc(int) { printf("CParent VFunc(int)\n"); }
};

class CChild : public CParent
{
public:
// using 부모::함수명 을 통해 자식의 범위에서 부모의 함수 이름이 보이도록 하자.
	using CParent::Func; 
	using CParent::VFunc;
	
	void Func(int a) 
	{
		printf("CChild Func(int)\n");
	}
	void VFunc() override { printf("CChild VFunc()\n"); }
};

int main()
{
	// 방법 2

	CChild c;

	c.VFunc(1);  // CParent::VFunc(int)
	c.Func();    // CParent::Func();
	
	c.Func(2.5); // CParent::Func(double)
	c.Func(1);	 // CChild::Func(int)
	c.VFunc();	 // CChild::VFunc();

using을 사용해 자식 클래스에서 함수 이름 탐색을 할 때 부모의 함수 이름이 보이도록 했고, 그림으로 그려보았다.

VFunc()과 같이 CParent클래스와 CChild 클래스에 모두 존재하는 경우, CChild에 존재하는 것을 우선으로 한다.

결과

profile
낙서장

0개의 댓글