2010-03-16 2 views
0

나는 알고있다 why 개인 가상 기능을 사용하고 싶지만, 어떻게 구현할 수 있습니까? 예를 들어파생 클래스 내에서 개인 가상 함수를 구현하는 방법은 무엇입니까?

:

class Base{ 
[...] 
private: 
virtual void func() = 0; 
[...] 
}; 

class Derived1: public Base{ 
    void func() 
    { //short implementation is ok here 
    } 
}; 

class Derived2: public Base{ 
    void func(); //long implementation elsewhere (in cpp file) 
}; 

[...] 

void Derived2::func() 
{ //long implementation 
} 

첫 번째 버전은 확인하지만 항상 가능하다. 두 번째 버전이 단순히 숨기는 이름이 아닙니까? Dereived2의 클래스 선언에서 수행 할 수없는 경우 을 Derived2으로 어떻게 정의합니까?

감사

+1

는 왜 개인으로

너의 진정,

SeargX이 있습니까? 보호받는 것이 더 합리적 일 것입니다. 정교하게 만들어 주시겠습니까? – dbemerlin

+4

'Derived2 :: func()'은'Base :: func()'에 대한 올바른 재정의 (override)입니다. 정확히 작동하지 않는 것은 무엇입니까? –

+1

"항상 가능한 것은 아니지만"에 대해 자세히 설명해 주시겠습니까? – philsquared

답변

4

어떻게는 Base::func()Derived2의 정의합니까?

(이 될 수있는 무엇이든) "Derived2Base::func()"정의하지 않습니다, 당신은 Derived2::func()을 정의합니다. 이것은 나를 위해 잘 컴파일 :

#include <iostream> 

class Base{ 
private: 
virtual void foo() = 0; 
public: 
    void bar() {foo();} 
}; 

class Derived: public Base{ 
    void foo(); 
}; 

void Derived::foo() 
{ 
    std::cout << "inside of 'Derived1::foo()'\n"; 
} 

int main() 
{ 
    Derived d; 
    Base& b = d; 
    b.bar(); 
    return 0; 
} 

무엇이 문제입니까?

+0

내 문제는'Derived :: foo()'가 Derived의 새 함수를 선언하고 정의한다는 것입니다 (Base :: foo() 정의하지 않음). 하지만 bar() 함수를 좀 더 추악한 방식으로 정의한다면'void bar() {((Base *) this) -> foo();}' 을 볼 수 있습니다. 그러므로 Base :: foo()가 정의되었습니다 ... 다시 한번 감사드립니다! ' – Dane

3

다형성과 접근성은 두 개의 분리 된 개념이다. 기본 클래스의 개인 가상 함수는 항상 무시할 수 있지만 기본 클래스 자체를 제외한 다른 곳에서 기본 클래스 버전을 호출 할 수는 없습니다. 또한 C++ FAQ Lite에는 꽤 긴 항목이 있습니다. 당신이 Dereived2의 클래스 선언 내에서 그것을 할 수없는 경우

+0

내 질문은 : 정확히 어떻게? – Dane

+0

@Kristo : (public : : Base :: f;를 사용하고, myBase-> f()를 사용하여) 액세스 모드를 변경 한 파생 클래스를 통해 참조하면 private 기본 클래스 함수를 호출 할 수 있습니다. –

+2

@Kristo 어쨌든 순수 가상이라면 왜 기본 클래스 버전을 호출할까요? 컨텍스트가 템플릿 메서드를 구현하는 것처럼 보입니다. 따라서 기본 클래스 자체에서만 호출된다는 것입니다. – philsquared

-2

여기에서 이해할 수있는 것은 다형성을 시도하는 것입니다.

다형성을 달성하기 위해 따라야하는 4 가지 규칙이 있습니다.

  1. 기본 클래스에서 상속해야합니다.
  2. 함수는 모든 클래스에서 동일한 이름을 가져야합니다.
  3. 모든 기능 앞에는 virtual 키워드가 필요하고, 자식 기능 끝에는 override 키워드가 필요합니다.
  4. 기본 클래스에서 포인터를 사용해야하고 "new"키워드를 사용하여 하위 유형으로 정의해야합니다.

코드 예는 awesome wiki page을 참조하십시오.

희망이 당신이 원하는 것입니다. ^^

+1

# 3과 # 4는 C++에도 적용되지 않습니다. – sbi

+0

음 ... 네, 그렇습니다. 어쩌면 당신은 ovveride 키워드를 사용하도록 강요 당하지 않을 것입니다. 당신이하고 싶은 것에 달려 있지만 C++에 확실히 적용됩니다. – SeargX

+1

오버라이드는 C++에서 MS 익스텐션으로 만 지원됩니다 (어쨌든 C++/CLI 용으로 구현해야했기 때문일 수도 있습니다). 그것은 표준 C++의 일부가 아닙니다 – philsquared