2008-10-23 84 views
12

我想要一个纯虚父类调用,像这样一个孩子实现一个功能:C++父类调用子虚拟功能

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

或者它不应该工作,我错了吗?

回答

2

一般会工作,但不适用于纯虚拟基类的构造函数中的调用。在构建基类时,子类覆盖不存在,因此您不能调用它。只要您在构建完整个对象后调用它,它就可以工作。

2

这是因为你的调用是在构造函数中。在构造函数完成之前,派生类将无效,因此您的编译器正在为此定下决心。

有两个解决方案:

  1. 执行调用以处理()在子类的构造函数
  2. 定义毛坯功能体用于过程如下面的例子:
class parent 
{ 
    public: 
    void Read() { //read stuff } 
    virtual void Process() { } 
    parent() 
    { 
     Read(); 
     Process(); 
    } 
} 
+0

这是危险的,定义一个空白父函数体并在其构造函数中调用它将导致只执行Process()的父部分(即无)。他可能希望将该调用作为虚函数解析,这在构造函数中是不可能的 – Pieter 2008-10-24 08:25:51

+0

确实:将调用空函数。这不是可行的解决方案。 – xtofl 2008-10-24 09:32:49

4

或者,建立一个工厂方法来创建对象并使构造函数为私有,工厂方法可以在构造之后初始化该对象。

0

你需要用在调用虚拟方法的对象中后,对象完全构造:

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; 
} 
2

足下越多,你可能只是引入某种功能像

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

肤浅问题是你调用一个还不知道的虚拟函数(对象是由Parent to Child构造的,因此vtable也是如此)。你的编译器警告过你。

必不可少的问题,据我所知,是你试图通过继承重用功能。这几乎总是一个坏主意。设计问题,可以这么说:)

本质上讲,你尝试实例化一个模板方法模式,从而分离出什么:先读一些数据(以某种方式),然后处理它(在某种方式)。

这可能会更好地处理聚合:将Processing函数赋予Template方法以在正确的时间调用。也许你甚至可以为Read功能做同样的事情。

聚集可以通过两种方式来完成:

  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()); 
    } 
};