2014-02-10 5 views
3

스택 오버플로를 검색했지만 내 질문에 정확히 대답하는 내용을 찾지 못했습니다. 이 클래스에서 파생 된 클래스에 의해 구현되고 싶습니다 순수 가상 함수가 들어있는 인터페이스 클래스가 있습니다.템플릿 클래스의 순수 가상 함수 재정의

나는이 인터페이스에서 파생 된 모든 클래스에서 재정의하고자하는 함수를 정의하는 BaseInterface을 호출 할 인터페이스가 있습니다. 이 예에서는 이라는 순수 가상 함수가 하나만 있다고 가정하고을 구현한다고 가정합니다. 이라는 클래스를 만들고 BaseInterface에서 상속받은 순수 가상 함수에 몇 가지 기능을 추가합니다. Base는 BaseInterface에 함수를 구현하지 않으므로 여전히 추상 클래스입니다.

나는 toImplement이 자신의 인스턴스를 실행할 때 발생하는 자료의 일반적인 기능의 모든 혜택을하지만 지정 자료에서 파생 된 여러 클래스가 있습니다. 이러한 클래스는 모두 구체적이어야하며 BaseInterface으로 설정된 모든 요구 사항을 충족해야합니다. 아래에서는 Derived이라는 클래스 중 하나를 정의합니다.

이 모든 것은 BaseInterface와 Base가 템플릿 화되지 않은 경우에 잘 작동합니다. 코드는 을 정의하지 않고자료에 정의하고 구현 (2.)하지 않고 잘 컴파일되고 실행됩니다.

그러나 을 구현하려면을 다른 유형으로 작동 시키십시오. 내가 이해 한 바로는 템플릿 기반 클래스에서 순수 가상 함수를 갖는 것이 좋습니다. 나는 언제 tryUsingImplemented에서 사용할 toImplement 모르는 자료 (1), 내가 자료 이후로 컴파일 할 수 없습니다에 toImplement를 정의하지 BaseInterface 일부 유형의 T.에 자료을 템플릿. 베이스에 정의를 추가하면 코드가 미리 컴파일되지만 링커는 Base :: toImplement 구현을 찾을 수 없습니다. 마지막으로, 내가 을 정의하고 구현할 경우 (1. 및 2.)에을 구현하면 코드가 컴파일됩니다.

더미 구현으로 을 구현하여을 Base에 구현 했으므로이 구현이 실행되기를 원치 않습니다. 또한 베이스에서 구현을 구현하기 때문에, 유도 된은 더 이상 구현하지 않아도됩니다. 이것은 BaseInterface 내 눈을 쓸데 없게합니다.

는 sombody 그 모든 가능한 경우 첫번째 자료에서 그것을 구현하지 않고, 에서이를 파생 toImplement 의 구현을 적용하는 방법을 가르치 려 수 있습니까?당신이 파생 클래스에서 호출하려는 경우

template <typename T> 
class BaseInterface { 
    virtual void toImplement(T & t) = 0; 
}; 


template <typename T> 
class Base : public BaseInterface<T> { 
bool m_useImplemented; 

public: 
    explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {} 

    void tryUsingImplemented(T & t) { 
     if (m_useImplemented) 
     toImplement(t); 
    } 

protected: 
    // 1: Defining toImplement pure virtual function in Base 
    virtual void toImplement(T & t); 
}; 

// 2. Implementing a version of toImplement in Base which does nothing 
template <typename T> 
inline void Base<T>::toImplement(T & t) { 
    // do nothing 
} 

class Derived : public Base<int> { 
public: 
    explicit Derived(bool useImplemented) : Base<int>(useImplemented) {} 

protected: 
    // 3. implementing toImplement in Derived 
    void toImplement(T & t) { 
     std::cout << "Doing stuff for Derived" << std::endl; 
    } 

}; 
+0

순수 가상 기능에 대한 정의를 제공 할 수 있습니다. 파생 클래스가'Base :: toImplement'에 대한 가상이 아닌 호출을 수행하는 것을 원하지 않으면 private 함수로 만듭니다. – Simple

+0

가능한 한 내 문제를 단순화하려고 노력했지만 실제로 BaseInterface :: toImplement를 protected로 정의하는 것을 잊어 버렸습니다. 원래 코드에 있었으므로 문제는 액세스가 아닙니다. – user3293204

답변

2

나중에 참조 할 수 있도록 컴파일러 오류 메시지를 제공하면 도움이됩니다.

그러나이 경우에는 알고 있습니다. 코드에 두 가지 오류가 있습니다.

  1. toImplementBaseInterface에 비공개입니다.
  2. tryUsingImplemented의 조회는 기본 클래스에서 보지 않습니다. lookup in dependent bases 문제가 발생했습니다. 문제를 해결하려면 this->toImplement(t)으로 작성하십시오.
+0

답해 주셔서 감사합니다. 나는이 문제가 실제로 종속적 인 기반에서 찾아 왔다고 믿는다. Base의 순수 가상에 대한 정의와 구현을 제거하고 호출을 다음으로 대체했습니다. this-> toImplement와 컴파일러는 이제 BaseInterface를 사용하는 것을 알고 있습니다 :: toImplement – user3293204

0

당신은 BaseInterface에서 protectedtoImplement를 선언해야합니다. 파생 클래스에서 우선하는 모든 메서드를 제거하고 Derived::toImplement의 매개 변수 유형을 int으로 바꿨으며 정상적으로 컴파일됩니다. 후자는 Derived이 템플릿이 아니기 때문에 필요하므로 Base에 전달 된 템플릿 매개 변수를 사용해야합니다.

#include <iostream> 

    template <typename T> 
    class BaseInterface { 
    protected: 
    virtual void toImplement(T & t) = 0; 
    }; 


    template <typename T> 
    class Base : public BaseInterface<T> { 
    bool m_useImplemented; 

    public: 
    explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {} 

    void tryUsingImplemented(T & t) { 
     if (m_useImplemented) 
      toImplement(t); 
    } 
    }; 

    class Derived : public Base<int> { 
    public: 
    explicit Derived(bool useImplemented) : Base<int>(useImplemented) {} 

    protected: 
    // 3. implementing toImplement in Derived 
    void toImplement(int & t) { 
     std::cout << "Doing stuff for Derived" << std::endl; 
    } 

    }; 
+0

답변 해 주셔서 감사합니다! BaseInterface에 보호 된 키워드를 추가하는 것을 잊어 버렸지 만 문제가 아니기 때문에 원래 코드에 있습니다. 문제는 컴파일러가 템플릿 T에 의존하여 toImplement를 알지 못하는 Base에서 ImImplement를 호출하는 것입니다. 이것은 this-> toImplement – user3293204

+0

흠을 사용하여 수정되었습니다. 음, clang을 사용하면 문제없이 컴파일됩니다. 그러나 여전히, 그 문제에 대해 잘 알고 있습니다. –

관련 문제