티스토리 뷰

반응형

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

파생 클래스의 이름은 기본 클래스의 이름을 가린다.

 

 

Scope (유효 범위)

1
2
3
4
5
6
int x;   // 전역 변수
void someFunc()
{
    double x;   // 지역 변수
    std::cin >> x;   // 입력을 받아, 지역 변수 x에 새 값을 읽어 넣음
}
cs

*안쪽 유효 범위에 있는 이름이 바깥쪽 유효범위에 있는 이름을 가림

 

상속

부모 클래스에 속해 있는 것을 자식 클래스 멤버 함수 안에서 참조하는 문장이 있으면 컴파일러는 참조 대상을 바로 찾아낼 수 있음
자식 클래스의 유효 범위가 부모 클래스의 유효 범위 안에 중첩되어있음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
class Base 
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf2();
    void mf3();
};
 
class Derived : public Base 
{
public:
    virtual void mf1();
public:
    void mf4();
};
 
//mf4가 파생 클래스에서 다음과 같이 구현되어 있다고 가정.
void Derived::mf4()
{
    //TODO: 
 
    mf2();
 
    //TODO:
}
 
위 함수 안의 mf2를 발견하고, mf2가 어느 것에 대한 이름인지를 찾음
Derived 클래스에서 보이지 않으면 Base에서 찾음
자식 클래스에 오버로딩된 함수는 부모 클래스의 오버로드 버전도 가려버림
 
class Base 
{
private :
    int x;
public :
    virtual void mf1() = 0;
    virtual void mf1(int);                 //오버로드
    virtual void mf2();
public:    
    void mf3();
    void mf3(double);                   //오버로드
};
 
class Derived : public Base 
{
public:
    virtual void mf1();
public:    
    void mf3();
    void mf4();
};
 
기본 클래스에 있는 함수들 중에 mf1 및 mf3 이라고 이름이 붙은 것은 모두 파생 클래스에 들어 잇는 mf1 및 mf3에 의해 가려지고 만다.
 
void main()
{
    Derived d;
    
    int x;
 
    d.mf1();   // Derived::mf1을 호출
    d.mf1(x);   // 에러. Dervied::mf1이 Base::mf1을 가림
    d.mf2();   // 문제 없음. Base::mf2를 호출
    d.mf3();     // 문제 없음. Dervied::mf3을 호출
    d.mf3(x);   // 에러. Derived::mf3이 Base::mf3을 가림
}
이렇게 가려진 오버로드 버전은 using 선언을 써서 끄집어 낼 수 있음
 
class Base 
{
private :
    int x;
public :
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
 
public:
    void mf3();
    void mf3(double);
};
 
class Derived : public Base 
{
public:
    using Base::mf1;                    //가려진 이름은 using 선언을 써서 끄집어 낸다.
    using Base::mf3;
public:    
    virtual void mf1();
public:
    void mf3();
 
};
 
void main()
{
    Derived d;
 
    int x;
    
    d.mf1(); 
    d.mf1(x);   // 이제 성공. Base::mf1 을 호출
    d.mf2(); 
    d.mf3();
    d.mf3(x);   // 이제 성공. Bas.mf3 을 호출
}
private으로 상속받으면 using 선언으로 해결 할 수 없음
 
 
 
해결방법 => fowarding 함수를 만듬
 
class Base 
{
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
};
 
class Derived : private Base 
{
public:
    virtual void mf1()   // 포워딩 함수임. 암시적으로 인라인 함수가 됨
    {
       Base::mf1(); 
    }
};
 
void main()
{
    Derived d;
 
    int x;
    d.mf1();
    d.mf1(x);   // 에러! Base::mf1()은 가려져있음
}
 
 
 
 
 
cs

 

결론

파생 클래스의 이름은 기본 클래스의 이름을 가린다. Public 상속에서는 이런 이름 가림 현상은 바람직하지 않다.
가려진 이름을 다시 볼 수 있게 하는 방법은, using 선언 혹은 전달 함수를 쓸 수 있다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함