2012-06-03 4 views
0

CodeBlocks를 사용하고 있으며 다음 코드는 컴파일되지 않습니다. 나는 다음과 같은 오류가C++ 가상 함수가 인식되지 않습니다.

#include <iostream> 
using namespace std; 

class Shape 
{ 
     public: 
       Shape(); 
       virtual void reset(); 
     private: 
       int color; 
}; 

class Point : public Shape 
{ 
     private: 
     double a,b; 
}; 

void Shape::reset() 
{ 
     cout<<"Shape reset\n"; 
} 

void Point::reset() 
{ 
     Shape::reset(); 
     cout<<"Point reset"; 
} 

Shape::Shape() 
{ 
     reset(); 
} 

int main() 
{ 
     Shape s; 
     Point o; 
} 

: 다음과 같이

코드는

(이것은 컴파일되지 않는 이유를 내가 물어보고 싶은 유일한 것은 그래서 그것은 몇 가지 C++ 함정에 관한 것입니다)

no `void Point::reset()' member function declared in class `Point' 

답변

6

당신은 당신의 Point 클래스 본문에 함수의 선언을 추가해야합니다

,
class Point : public Shape 
{ 
public: 
    virtual void reset(); 
private: 
    double a,b; 
}; 

(virtual은 기본 클래스에 virtual로 선언되어 있기 때문에 불필요합니다. 그러나 알림으로 추가하는 것이 도움이) 대신에 다음과 같이 선언한다

+0

오, 고마워요. 제가 Shape에서 Point를 확장하여 직접 작동하지만, 지금은 그렇지 않다는 것을 알았습니다. – delegat

+0

@delegat - 재정의를 선언해야하는 주 이유는 호출 최적화입니다. 컴파일러는 종종 객체의 정확한 유형을 알고 있으며,이 경우 VMT 액세스를 최적화합니다 (가상 메소드보다는 직접 메소드를 호출 함). 그러나'Point :: reset'의 구현이 컴파일 유닛에서만 볼 수 있다면'Point'에 대해 알고있는 다른 컴파일 유닛에서'Point' 객체에 대해'Shape :: reset'을 잘못 호출하게됩니다 그러나'Point :: reset'에 대해서는 그렇지 않습니다. –

0

:. 가상 함수가 아무 일도하지 않기 때문에, 당신은 단지 선언에 괄호를 추가 할 수

class Shape 
{ 
     public: 
       Shape(); 
       virtual void reset(){}; 
     private: 
       int color; 
}; 

공지 사항 괄호 . 가상 함수이므로 기본 클래스를 상속 할 때 다시 정의되도록 설계되었습니다. 따라서 Point::reset() 함수에서 실제로 Shape::reset()으로 전화 할 수는 없습니다. 또한 Point 클래스에서 새 함수를 다시 정의해야합니다. 이렇게 :

class Point : public Shape 
{ 
    public: 
     void reset(); 
} 

Point::reset과 같은 기능을 사용할 수 있습니다.

관련 문제