基类构造函数对派生类C ++不可见

时间:2013-09-11 16:13:38

标签: c++ oop inheritance virtual-functions

我正在用C ++编写玩具正则表达式引擎作为学习练习,我遇到了编译器错误。以下是实现不同表达式子类型的类的定义:

// ***************************************************************
// ***************************************************************

  class RegexExpression {
  public:

    virtual RegexResult match(std::string);
  };

// ***************************************************************

  class RegexTerm : public virtual RegexExpression {
  public:
    RegexTerm(char c) : _matchChar(c) {}

    RegexResult match(std::string);

  private:

    char _matchChar;
  };

// ***************************************************************

  class RegexNil : public virtual RegexExpression {

  public:

    RegexResult match(std::string);

  };

// ***************************************************************
// ***************************************************************

  class RegexBinaryExpression : public virtual RegexExpression {
  public:
    RegexBinaryExpression
    (RegexExpression &lhs, RegexExpression &rhs) :
      _lhs(lhs), _rhs(rhs) {}

  protected:

    RegexExpression _lhs;
    RegexExpression _rhs;


  };

// ***************************************************************

  class RegexOr : public RegexBinaryExpression {
  public:

    RegexResult match(std::string);

  };

// ***************************************************************

  class RegexAnd : public RegexBinaryExpression {
  public:

    RegexResult match(std::string);

  };

然而,当我尝试实例化RegexOr时,例如:

RegexOr regex(RegexTerm('a'), RegexNil());

然后我收到编译器错误,告诉我RegexBinaryExpression中的2参数构造函数不可见。

如果我在RegexOr中明确定义构造函数,例如:

RegexOr(RegexExpression &l, RegexExpression &r) : RegexBinaryExpression(l, r) {}

然后我被告知RegexNil无法转换为RegexExpression。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

至少在C ++ 11之前,你必须自己在RegexOr中实现构造函数。但是,您将其实现为接受非const 引用参数,然后您尝试从临时绑定,该语言禁止使用该参数。

而是通过const引用(或者甚至可能通过值)获取参数:

RegexBinaryExpression(const RegexExpression &lhs, const RegexExpression &rhs)
: _lhs(lhs)
, _rhs(rhs)
{}

RegexOr(const RegexExpression &l, const RegexExpression &r) : RegexBinaryExpression(l, r) {}

答案 1 :(得分:2)

您无法将临时对象传递给非const引用参数。要使其编译,您需要将参数更改为const引用(或按值)。

但是你有一个更大的问题。将参数复制到RegexBinaryExpression的成员时,它们将存储为RegexExpression对象而不是派生对象。有关派生类型的信息将丢失。这称为对象切片。

您需要动态分配正则表达式对象并在类中存储指向它们的指针。我会推荐智能指针。您还可以将类型的正则表达式对象存储在类,模板参数中,而不是存储在继承层次结构中。这可能更难实施,并且有一些缺点。