【问题标题】:Base class constructor not visible to derived class C++派生类 C++ 不可见基类构造函数
【发布时间】:2013-09-11 16:13:38
【问题描述】:

我正在用 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。

我在这里做错了什么?

【问题讨论】:

  • 只是一个观察。 Regex 代表 RegularExpression,因此您的类名似乎是多余的:RegularExpressionExpression。这只是一个练习,所以我想这并不重要,但这会让我发疯:D
  • 究竟是什么错误? “来自 RegexBinaryExpression 的 2 个参数构造函数不可见。” ???
  • 您还应该在基类中放置一个虚拟析构函数。
  • @crush - 我知道。我发帖后就注意到了。
  • 确切的错误是no matching function for call to ‘Regex::RegexOr::RegexOr(Regex::RegexExpression&, Regex::RegexNil)

标签: c++ oop inheritance virtual-functions


【解决方案1】:

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

改为通过 const 引用(甚至可能通过值)获取参数:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 不需要动态分配对象,并且给定树结构,如果这样做,则不需要智能指针。
    • @JamesKanze 你能解释一下吗?
    猜你喜欢
    • 2015-08-18
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2018-07-21
    • 1970-01-01
    • 2020-11-28
    • 2021-02-14
    相关资源
    最近更新 更多