2012-05-31 3 views
4

이 코드가 컴파일되지 않는 이유는 무엇입니까? (GCC 4.7.0)파생 포인터에서 공용 기본 멤버에 액세스 할 수 없습니다.

// Class with a simple getter/setter pair. 
class Base { 
public: 
    Base() : m_Value(0) { } 

    virtual ~Base() { } 

    // Getter 
    virtual int value() { return m_Value; } 

    // Setter 
    virtual void value (int Val) { m_Value = Val; } 

private: 
    int m_Value; 
}; 

// Derived class overrides the setter. 
class Derived : public Base { 
public: 
    void value (int Val) { 
      // do some stuff here... 
    } 
}; 

int main() 
{ 
    Derived * instance = new Derived(); 
    int x = instance->value(); // ERROR 
    return 0; 
} 

빌드 로그 : 자료에서

test.cpp: In function 'int main()': 
test.cpp:29:25: error: no matching function for call to 'Derived::value()' 
test.cpp:29:25: note: candidate is: 
test.cpp:21:7: note: virtual void Derived::value(int) 
test.cpp:21:7: note: candidate expects 1 argument, 0 provided 

이유는 컴파일러가 실패하는보고 '(int 값)은'시 * 파생 사용하고 계십니까?

Derived * instance = new Derived(); 

변경

Base * instance = new Derived(); 

에 작품 (하지만 내 경우에 파생 포인터가 필요합니다).

기본 getter/setter 함수의 이름을 getValue() 및 setValue (int)가되도록 변경합니다. 내 코드에 여러 가지 해결 방법을 사용할 수 있지만이 코드가 컴파일되지 않는 이유에 대해 궁금합니다.

+2

의 중복 가능성 [이유는 무엇입니까 기본 클래스의 파생 클래스 숨기기 다른 오버로드에서 재정의 된 기능? (http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the) – Mat

답변

11

다음은 언어 작동 방식입니다. 하위 클래스가 이름의 멤버를 재정의하면 상위에있는 재정의되지 않은 이름이 모두 숨겨집니다. 이는 실수로 세트로 겹쳐 써야하는 기본 및 상위 메소드를 결합하지 않기위한 것입니다.

자식 클래스에 using Base::value;을 넣어 부모 메소드를 가져올 수 있습니다.

+0

감사합니다. 문제가 잘 해결됩니다. – QuasarDonkey

3

파생 클래스의 함수 value은 기본 클래스의 함수을 숨 깁니다.

당신은 파생 클래스의 범위에 기본 클래스 기능을 가지고해야합니다

class Derived : public Base { 
public: 

    using Base::value; //<---- note this 

    void value (int Val) { 
      // do some stuff here... 
    } 
}; 
관련 문제