본문 바로가기
Object Oriented Programming(C++)/Effective C++

Effective C++ | 항목 33 상속된 이름을 숨기는 일은 피하자

by continue96 2023. 5. 20.

Effective C++ 항목 33

 

항목 33 상속된 이름을 숨기는 일은 피하자

33.1 유효 범위

  • 함수 유효 범위
    • 컴파일러는 함수에서 지역 유효 범위 → 전역 유효 범위 순으로 변수의 이름을 찾는다.
    • 타입과 상관없이 이름이 같은 변수를 찾는다.
int x;

void Function() {
	// 지역 변수 double의 이름 x가 전역 변수 int의 이름 x를 가립니다.
	double x;
	cin >> x;
}

 

  • 클래스 유효 범위
    • 컴파일러는 클래스에서 지역 유효 범위 → 자식 클래스 유효 범위 → 부모 클래스 유효 범위 → 전역 유효 범위 순으로 함수 혹은 변수의 이름을 찾는다.
    • 함수 혹은 변수의 반환 타입, 매개변수 타입과 상관없이 이름이 같은 함수 혹은 변수를 찾는다.
class Parent {
private:

public:
	// 순수 가상 함수
	virtual void m1() = 0;
	virtual void m1(int i);

	// 가상 함수
	virtual void m2();

	// 비가상 함수
	void m3();
	void m3(double d);
};

class Child : public Parent {
public:
	// 자식 클래스 멤버 함수의 이름 m1()이 부모 클래스 멤버 함수의 이름 m1(int)을 가립니다.
	virtual void m1();

	// 자식 클래스 멤버 함수의 이름 m3()이 부모 클래스 멤버 함수의 이름 m3(double)을 가립니다.
	void m3();
	void m4();
};

Child c;
int i, double d;

// 이름이 가려져서 호출할 수 없습니다.
c.m1(i);
c.m3(d);

 

33.2 오버로드된 함수 재정의

 33.2.1 using 선언

  • 부모 클래스에 있는 멤버 함수의 이름을 using으로 명시적으로 선언한다.
    • 부모 클래스에 오버로드된 멤버 함수가 있고 멤버 함수 중 일부만 자식 클래스에서 재정의한 경우
    • using 선언으로 재정의되지 않은 오버로드된 멤버 함수를 호출할 수 있다.
class Parent {
private:

public:
	// 순수 가상 함수
	virtual void m1() = 0;
	virtual void m1(int i);

	// 가상 함수
	virtual void m2();

	// 비가상 함수
	void m3();
	void m3(double d);
};

class Child : public Parent {
public:
	// 부모 클래스의 m1(int)를 호출할 수 있습니다.
	using Parent::m1;

	// 부모 클래스의 m3(double)를 호출할 수 있습니다.
	using Parent::m3;

	virtual void m1();
	void m3();
	void m4();
};

Child c;
int i, double d;
c.m1(i);
c.m3(d);

 

 33.2.2 전달 함수

  • private 상속의 경우, 전달 함수(forwarding function)로 부모 클래스의 멤버 함수 중 일부만 상속할 수 있다.
class Parent {
public:
	// 순수 가상 함수
	virtual void m1() = 0;
	virtual void m1(int i);
};

class Child : private Parent {
public:
	virtual void m1() {
		Parent::m1();
	}
};

Child c;
int i;
c.m1();
// 이름이 가려져서 호출할 수 없습니다.
c.m1(i);

 

NOTE
① 자식 클래스의 이름은 부모 클래스의 이름을 가리는데, 이는 바람직하지 않다.
② using 선언 혹은 전달 함수로 가려진 이름을 다시 볼 수 있다.

댓글