ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective C++...31
    일지 2022. 8. 2. 08:40

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

    C++의 유효 범위 탐색 과정과 문제

    만약 프로그램 실행 중 특정 함수가 발견됐다면 해당 함수를 찾기 위해 컴파일러는 다음의 과정을 밟게 된다.

    1. 지역의 유효 범위 탐색
    2. Derived 클래스의 유효 범위 탐색
    3. Base 클래스의 유효 범위 탐색
    4. 네임 스페이가 있으면 네임 스페이스 내부 범위 탐색
    5. 전역 유효범위 탐색

     

    이 과정에서 Base 클래스에 존재하는 함수와 동일한 이름의 함수를 Derived 클래스에서 생성했다면 함수의 매개 변수가 다르거나 비가상 함수라고 하더라도 Base 클래스의 함수의 이름이 가려지게 된다.


    class Base {private:
        int x;
    public:    virtual void mf1() = 0;

        virtual void mf1(int);

        virtual void mf2();    void mf3();

        void mf3(double);

        ...};class Derived: public Base {public:

        virtual void mf1();

        void mf3();

        void mf4();    ...};

     

    Derived d;int x;...d.mf1(); // Derived의 mf1 호출d.mf1(x); // 에러, Base::mf1이 가려짐

     

    d.mf2();

     

    d.mf3(); // Derived의 mf3 호출d.mf3(x); // 에러, Base::mf3이 가려짐


     

    이름 가리기 문제 해결 방법

    이러한 문제를 해결하는 방법은 Derived 클래스에서 Base 클래스의 함수를 사용한다는 것을 using으로 선언해주는 것이다.


    class Derived: public Base {

    public:

        using Base::mf1;

        using Base::mf3;

     

        virtual void mf1();

        void mf3();

        void mf4();
        ...

    };

     

    Derived d;

    int x;

    ...

    d.mf1(); // Derived의 mf1 호출

    d.mf1(x); // Base의 mf1 호출

     

    d.mf2();

     

    d.mf3(); // Derived의 mf3 호출

    d.mf3(x); // Base의 mf3 호출


     

    그런데 상속받은 함수 중 하나의 함수만 상속받고 싶을 때는 using은 이름 단위로 처리를 하기 때문에 using으로는 처리가 불가능하다.

     

    따라서 이런 경우에는 전달 함수를 사용해 처리할 수 있다.


    class Derived: private Base {

    public:

        virtual void mf1()

        {

            Base::mf1();

        }

        ...

    };


     

    댓글

Designed by Tistory.