C ++ 부모 클래스 자식 가상 기능을 호출합니다
-
04-07-2019 - |
문제
순수한 가상 부모 클래스가 다음과 같은 기능의 자식 구현을 호출하기를 원합니다.
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 클래스의 생성자 내에서 호출은 작동하지 않습니다. 건설 된 기본 클래스가있을 때 하위 클래스 재정의가 존재하지 않으므로 호출 할 수 없습니다. 전체 객체가 구성되면 호출하는 한 작동해야합니다.
통화가 생성자에 있기 때문입니다. 파생 클래스는 생성자가 완료 될 때까지 유효하지 않으므로 컴파일러가이를 위해 배선하는 데 적합합니다.
두 가지 해결책이 있습니다.
- 파생 클래스의 생성자에서 Process ()를 호출하십시오.
- 다음 예에서와 같이 프로세스에 대한 빈 기능 본문을 정의하십시오.
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 : 런타임 바인딩
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() );
}
};