[英]C++ Parent class calling a child virtual function
我想要一个纯虚拟父类来调用函数的子实现,如下所示:
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;
}
这应该工作,但我得到一个未链接的错误:/这是使用VC ++ 2k3
或者不应该工作,我错了吗?
以下文章的标题说明了一切: 在构造或销毁期间永远不要调用虚函数 。
或者,创建一个用于创建对象的工厂方法并使构造函数成为私有,然后工厂方法可以在构造之后初始化对象。
通常可以工作,但不适用于纯虚基类的构造函数中的调用。 在构造基类时,子类覆盖不存在,因此您无法调用它。 只要在构造完整个对象后调用它,它就应该有效。
这是因为你的调用是在构造函数中。 在构造函数完成之前,派生类将无效,因此编译器正确地指责您。
有两种解决方案:
class parent
{
public:
void Read() { //read stuff }
virtual void Process() { }
parent()
{
Read();
Process();
}
}
再向前迈一步,你可以介绍一些类似的功能
class parent
{
public:
void initialize() {
read();
process();
}
}
在完全构造对象之后,您需要在一个调用virtual方法的对象内部进行包装:
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;
}
表面上的问题是你调用了一个尚未知道的虚函数(对象是从父对子构造的,因此vtable也是如此)。 你的编译器警告过你。
据我所知, 基本问题是您尝试通过继承来重用功能。 这几乎总是一个坏主意。 一个设计问题,可以这么说:)
本质上,您尝试实例化模板方法模式,将什么与何时分开:首先读取一些数据(以某种方式),然后处理它(以某种方式)。
这可能会更好地与聚合一起工作:将Processing函数提供给在正确的时间调用的Template方法。 也许你甚至可以为Read功能做同样的事情。
聚合可以通过两种方式完成:
示例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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.