2011-04-14 2 views
2

막대 및 상자는 Foo의 파생 클래스이며 Foo는 가상 함수 F()를 가지고 막대 및 상자는 둘 다 함수 F()를 갖습니다. 내가 이해, 다형성 올바르게 Bar.F() 또는 Bar.F() 대신 Box.F() Bar.F() 수 Foo.F() 개체를 여부를 알지 않고 일부 런타임 루틴을 사용하여 재정의 할 수 있습니다. 바 또는 상자.C++ 다형성을 정확히 이해합니까?

Foo * boxxy = new Box;
boxxy->F();

권리 F()를 호출 마지막 줄 (이 경우, Box.F()) 박시는 상자 또는 바 또는 푸하는지 여부와 상관없이 (에 : 그것은이 같은 뭔가 이 경우 가상 Foo.F()의 구현이 호출됩니다.

이 권리를 이해합니까? boxxy가 Box 포인터 인 경우 무엇이 변경됩니까? 파생 클래스에 F()에 대한 재정의가 없으면 어떻게됩니까? 마지막으로 기본 클래스에 대한 함수를 구현하지 않고 다형성을 허용하려면 빈 함수 본문을 작성하고 가상으로 선언합니까? 감사.

답변

2

거의 바로이 상속 트리를 고려 Bar으로 변환하십시오. :)
그럼 Foo<->BarFoo<->Box 일 뿐이며 절대로 Bar<->Box입니다. 다음으로 boxxyBox 포인터 인 경우 Box::F 함수가 제공된 경우에만 호출됩니다.
그리고 마지막으로,이 같은 pure virtual을 선언, 특정 기능을 구현하는 서브 클래스를 강제로 : Func를 구현해야합니다

이제
virtual void Func() = 0; 
// note this --- ^^^^ 

서브 클래스 (이 경우 BarBox에), 다른 사람들이 실패합니다 컴파일하기.

+0

고마워요. 그냥 호기심에서, 당신은 0 대신에 NULL을 사용할 수 있습니까? –

+0

@Brandon : 아니오, 순수 가상 함수를 선언 할 때 아닙니다. 필요한 exakt 토큰은'= 0'이며 다른 것은 없습니다. 또한, 나는 당신이'NULL' 대신'0'을 사용하도록 권장 할 것이고, C++ 0x가 오면 포인터에'nullptr'을 사용할 것입니다. :) – Xeo

0
  • 이 권리를 이해합니까? 예, 함수가 가상 함수로 선언 된 경우 예.
  • boxxy가 Box 포인터 인 경우 어떤 변경 사항이 적용됩니까? 기능이 가상인지 아닌지에 따라 다릅니다. 가상 함수는 항상 적절한 유도 함수 인 을 호출하게됩니다. 비 가상 함수는 포인터의 유형을 기반으로 버전을 호출합니다.
  • 파생 클래스 에 F()에 대한 재정의가 없으면 어떻게됩니까? 은 기본 클래스 정의를 사용합니다.
  • 마지막으로, 기본 클래스에 대한 기능을 구현하지 않도록하지만 여전히 다형성, 당신은 단지 빈 함수 본문을 작성하고 그것을 가상 선언 할 수 있도록? 순수하게 virtual : virtual void F() = 0으로 선언 할 수도 있습니다. 객체에 을 인스턴스화하려는 모든 클래스는이 함수를 훨씬 오버라이드하고 적절한 구현을 제공합니다. 지금과 같은 포인터를 한 경우

     Foo 
        / \ 
        Bar Box 
    

    :

    Bar* barry = new Box(); 
    

    당신은 nice compiler error를 얻을 수 있습니다을 이후 Box 수 없어, -

1

예 오른쪽 F()는 Foo 포인터를 통해 생성 한 개체 유형에 따라 호출됩니다.

Boxxy가 Box 포인터 인 경우 부모 클래스에 dynamic_cast를 수행 한 다음 F()를 호출하지 않는 한 Box의 포인터 만 F() 또는 파생 클래스의 F() 중 하나를 호출 할 수 있습니다.

당신이 그렇게 같은 순수 가상로 정의 기본 클래스에 구현하는 것을 방지하려면

class Foo 
{ 
public: 
    virtual void F() = 0; //notice the = 0, makes this function pure virtual. 

}; 
1

그리고 어떤 변화 박시는 상자 포인터 인 경우?

Foo에서 상속받지 않은 Box의 메소드에 대한 액세스를 허용합니다. Bar는 Box에서 파생되지 않기 때문에 Box 포인터는 Bar 객체를 가리킬 수 없습니다.

파생 클래스 에 F()에 대한 재정의가 없으면 어떻게됩니까?

기본 클래스에서 F() 구현을 상속받습니다.

마지막으로, 기본 클래스에 대한 기능을 구현하지 않도록하지만 여전히 다형성, 당신은 단지 빈 함수 본문을 작성하고 그것을 가상 선언 할 수 있도록?

다형성을 수행하는 올바른 방법은 아닙니다. 기본 클래스의 가상 함수에 대한 구체적인 구현을 생각해 낼 수없는 경우 해당 함수를 순수 가상으로 만들고 빈 함수로 구현하지 마십시오. 이

class Foo 
{ 
private: 
    Foo() {}; 
public: 
    void func() const { std::cout << "Calling Foo::func()" << std::endl; } 
}; 

처럼 푸를 선언하고이

class Bar : public Foo 
{ 
private: 
    Bar() {}; 
public: 
    void func() const { std::cout << "Calling Bar::func()" << std::endl; } 
}; 

처럼 바 경우

1

다음

Foo* bar = new Bar(); 
bar->func(); 

푸 :: FUNC()를 호출. 이

class Foo 
{ 
private: 
    Foo() {}; 
public: 
    virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD 
}; 

처럼 푸를 선언하면

다음

Foo* bar = new Bar(); 
bar->func(); 

바 :: FUNC()를 호출.

관련 문제