2013-03-19 2 views
0

일반 메서드가있는 인터페이스가 있는데 어떻게 호출해야합니까?C++ 구현 된 가상 클래스에서 가상이 아닌 메서드 호출

class Animal{ 
    virtual void virtualFunction()=0; 
} 

class Cow : Animal{ 
    virtual void virtualFunction(){} 
    void nonVirtualFunction(){} 
} 

class main{ 
    Animal *a = new Cow(); 
    a->virtualFunction(); 
} 

^을 작동하지만, 내가 할 때 ...

a->nonVirtualFunction(); 

는 클래스 동물이 방법가 발생하지 않는 것을 말한다, 내가 알고 당연히, 하지만, 그 방법을 호출하는 가장 좋은 방법은입니까?

답변

3

첫 번째 장소에서 다형성 Animal 포인터를 저장하지 않는, Cow의 구성원 인 함수를 호출하려고하는 경우 :

Cow* c = new Cow(); 
c->nonVirtualFunction(); 

그것은 저장하는 이해가되지 않습니다 Cow 특정 방식으로 사용하려는 경우 CowAnimal*입니다.

당신은 런타임에 객체의 동적 유형을 확인 dynamic_cast를 사용할 수 있습니다

Animal* a = new Cow(); 
if (Cow* c = dynamic_cast<Cow*>(a)) { 
    c->nonVirtualFunction(); 
} 

그러나, 이것은 일반적으로 나쁜 디자인의 표시이다.

+0

정말로 고마워요. 나는 Cow * c = new Cow()를 사용할 것입니다. 과연! –

1

nonVirtualFunction을 호출하려면 Cow 포인터를 사용해야합니다. Animal 포인터는 Animal의 인터페이스를 가진 Cow의 SUBSET에 대한 포인터입니다.

nonVirtualFunction을 호출하는 유일한 방법은 Cow 포인터를 얻는 것입니다.

Cow *c = dynamic_cast<Cow*>(a); 

은 실제로 암소를 가리킨다 고 가정하면 그러한 포인터를 제공합니다.

+0

나는 Cow * c = new Cow(); 과연! hlp에 감사드립니다 –

1

더 나은 자신을 설명하기 위해 방법 대신 자리 실명을 사용합니다 :

class Animal{ 
    virtual void move()=0; 
} 

class Cow : Animal{ 
    virtual void move(){} 
    void moo(){} 
} 

int main() { 
    Animal *a = new Cow(); 
    a->move(); 
    a->moo(); // ERROR 
} 

음, 에러 과정의 왜 지구에 당신이 일반적인 Animalmoo을할까요? 따라서 문제는 을 Animal에 전화하는 방법이 아닙니다. 이 호출은 의미가 없으며 컴파일러는 우리가 알아 차리는 데 도움이됩니다.

class Animal{ 
    // Everything else, plus: 
    std::string Name() {return name;} 

private: 
    std::string name; 
} 

int main() { 
    Animal *a = new Cow(); 
    a->move(); 
    std::string animalName = a->Name(); // OK 
} 

당신이 볼 수 있듯이, 당신이있는 경우 :

이제 Animal는 예를 들어 서브 클래스에 재 작성 할 필요없이 모든 동물에 호출 할 수있는 비 가상 메서드가있을 수 있습니다 좋은 디자인은 문제가 사라집니다.

+1

흠 실제로 자리 표시 자 대신 실명을 사용하는 방법이 실제로 더 명확합니다! 그것을 할 것입니다 :) 하지만 고마움, 지금 실제로 대답을 가지고, 그냥 암소를 만들어야합니다 * C = 새로운 암소! –

관련 문제