문제

순수한 가상 부모 클래스가 다음과 같은 기능의 자식 구현을 호출하기를 원합니다.

class parent
{
  public:
    void Read() { //read stuff }
    virtual void Process() = 0;
    parent() 
    {
        Read();
        Process();
    }
}
class child : public parent
{
  public:
    virtual void Process() { //process stuff }
    child() : parent() { }
}

int main()
{
   child c;
}

이것은 작동하지만, indind 오류가 발생하지 않습니다 :/ 이것은 vc ++ 2k3를 사용하고 있습니다.

아니면 작동하지 않아야합니다. 내가 틀렸습니까?

도움이 되었습니까?

해결책

다음 기사의 제목은 모든 것을 말합니다. 건축이나 파괴 중에 가상 기능을 부르지 마십시오.

다른 팁

또는 객체를 생성하기위한 공장 방법을 만들고 생성자를 비공개로 만들면 공장 방법은 구성 후 객체를 초기화 할 수 있습니다.

일반적으로 작동하지만 Pure Virtual Base 클래스의 생성자 내에서 호출은 작동하지 않습니다. 건설 된 기본 클래스가있을 때 하위 클래스 재정의가 존재하지 않으므로 호출 할 수 없습니다. 전체 객체가 구성되면 호출하는 한 작동해야합니다.

통화가 생성자에 있기 때문입니다. 파생 클래스는 생성자가 완료 될 때까지 유효하지 않으므로 컴파일러가이를 위해 배선하는 데 적합합니다.

두 가지 해결책이 있습니다.

  1. 파생 클래스의 생성자에서 Process ()를 호출하십시오.
  2. 다음 예에서와 같이 프로세스에 대한 빈 기능 본문을 정의하십시오.
class parent
{
  public:
    void Read() { //read stuff }
    virtual void Process() { }
    parent() 
    {
        Read();
        Process();
    }
}

한 걸음 더 가면

class parent
{
    public:
        void initialize() {
            read();
            process();
        }
}

객체가 완전히 구성된 후 가상 메소드를 호출하는 객체 내부를 랩핑해야합니다.

class parent
{
  public:
    void Read() { /*read stuff*/ }
    virtual void Process() = 0;
    parent()
    {
        Read();
    }
};

class child: public parent
{
  public:
    virtual void Process() { /*process stuff*/ }
    child() : parent() { }
};

template<typename T>
class Processor
{
    public:
        Processor()
            :processorObj() // Pass on any args here
        {
            processorObj.Process();
        }
    private:
        T   processorObj;

};




int main()
{
   Processor<child> c;
}

그만큼 피상적 문제는 아직 알려지지 않은 가상 함수를 호출한다는 것입니다 (물체는 부모에서 자식으로 구성되므로 vtables도 마찬가지입니다). 당신의 컴파일러가 그것에 대해 경고했습니다.

그만큼 필수적인 내가 볼 수있는 한, 문제는 상속으로 기능을 재사용하려고한다는 것입니다. 이것은 거의 항상 나쁜 생각입니다. 말하자면 디자인 문제 :)

본질적으로, 당신은 템플릿 메소드 패턴을 인스턴스화하여 무엇 ~로부터 언제: 먼저 일부 데이터를 읽은 다음 (어떤 방식으로) 처리하십시오 (어떤 식 으로든).

이것은 아마도 집계에 훨씬 더 나은 작업을 수행 할 것입니다. 적절한 시간에 호출 할 템플릿 방법에 처리 기능을 제공합니다. 읽기 기능에 대해서도 똑같이 할 수도 있습니다.

집계는 두 가지 방법으로 수행 할 수 있습니다.

  1. 가상 함수 사용 (예 : 런타임 바인딩)
  2. 템플릿 사용 (즉, 시간 바인딩 컴파일)

예 1 : 런타임 바인딩

class Data {};
class IReader    { public: virtual Data read()            = 0; };
class IProcessor { public: virtual void process( Data& d) = 0; };

class ReadNProcess {
public:
    ReadNProcess( IReader& reader, IProcessor processor ){
       processor.process( reader.read() );
    }
};

예 2 : 컴파일 타임 바인딩

template< typename Reader, typename Writer > // definitely could use concepts here :)
class ReadNProcess {
public:
     ReadNProcess( Reader& r, Processor& p ) {
         p.process( r.read() );
     }
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top