【问题标题】:C++: use a pure virtual function in a non-virtual functionC++:在非虚函数中使用纯虚函数
【发布时间】:2012-05-05 19:09:07
【问题描述】:

我正在尝试创建一个基类来定义所有派生类的接口。

我想要一个函数,允许读取该类的配置文件,使用boost::property_tree 可以非常顺利地工作。我们称这个函数为readConfig。 这必须在每个派生类中定义,所以我将其设为纯虚拟。

我想重载基类中的readConfig函数,基类中的每个重载函数最终都会调用纯虚形式,例如:

class Base
{
    // ...
    void readConfig(string, string);                                 // read config from file
    virtual void readConfig(boost::property_tree::ptree, string) =0; // read config from ptree
}

void Base::readConfig(string filename, string entry)
{
     boost::property_tree::ptree pt;
     read_xml(filename, pt);
     readConfig(pt, entry);       // <= Calling pure virtual function!
}

基本上,字符串版本只是纯虚拟形式的快速包装器。当我编译这个时,我得到一个错误:

no known conversion for argument 1 from std::string to boost::property_tree::ptree`

看来,非虚拟函数(来自Base)未被识别为可用。我检查了我的派生类定义是否正常:

class Deriv : public Base
{
    // ...
    void readConfig(boost::property_tree::ptree, string); // implement virtual, error is on this line
}

void Deriv::readConfig( boost::property_tree::ptree pt, string entry)
{
    //...
}

请注意,我省略了很多const-correctnes,通过引用传递等,以使代码更具可读性。

我能做些什么来解决这个问题?在非虚函数中使用纯虚成员函数是个好主意吗?

【问题讨论】:

  • Deriv.h,我声明函数的那一行。
  • 您实际上不会在正确编写的程序中调用纯虚拟函数。相反,您会调用对应的最衍生的覆盖,其中至少有一个。
  • 你的程序真的会因为“调用纯虚函数”而崩溃吗?
  • @KerrekSB 不,它只会唠叨转化率
  • 编译器错误实际发生在哪里?当然,您不能指望从Derived 中获得Base:readConfig(string, string)除非您明确将其称为Base::readConfig(),或者将using Base::readConfig; 添加到Derived

标签: c++ inheritance pure-virtual


【解决方案1】:

请参阅标题为“警告的含义:Derived::f(char) 隐藏 Base::f(double)?”的常见问题解答项目。可在 FAQ 的众多镜像中找到,包括原始的 English version of the FAQ

在发布之前查看常见问题解答通常是个好主意。

很有可能您还会发现标题为“好的,但是有没有办法模拟这种行为,就好像动态绑定在我的基类构造函数?”,另外,如果这变得相关,那么您可能也有兴趣阅读my blog article about the DBDI problem

【讨论】:

  • 哇,就是这样……又浪费了一个下午!奇怪的是,他们在课堂上不教这个......非常感谢!
  • 我发现这是继承中最棘手的问题之一。避免这种情况的一种方法是仅从private 基类继承并通过usingpublic 接口中声明所需的成员(这反过来允许仅使用一个声明来声明重载成员)。
【解决方案2】:

明显的错字很明显:

virtual void readConfug

而不是

virtual void readConfig

此外,您正在实施的称为模板方法模式,仅供参考。

【讨论】:

  • 哎呀,把它放在stackoverflow上是个错字。是的,我知道这将是一种设计模式!
  • @romeovs 我没有看到代码有任何其他问题。您能否重现一个存在问题的最小示例 - 可以编译。
  • 我怀疑太多了..问题一定更深,可能是指针搞砸了。我想提出来,但问题是BaseDeriv 之间还有另一个纯虚拟类。我会看看我能做什么。
  • 这就是我现在所做的:我将纯虚函数重命名为别的东西 (readConfigS)。一切都很顺利。这是否澄清了问题?
  • -1 与问题无关,应该只是评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 2012-08-27
  • 2016-07-16
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
相关资源
最近更新 更多