1

学習課題としておもちゃの正規表現エンジンを 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 に変換できないと言われました。

ここで何が間違っていますか?

4

2 に答える 2

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) {}
于 2013-09-11T16:20:27.597 に答える
2

非 const 参照パラメーターに一時オブジェクトを渡すことはできません。コンパイルするには、パラメーターを const 参照 (または値による) に変更する必要があります。

しかし、あなたにはもっと大きな問題があります。パラメーターを RegexBinaryExpression のメンバーにコピーすると、それらは派生オブジェクトではなく RegexExpression オブジェクトとして格納されます。派生型に関する情報は失われます。これは、オブジェクトのスライスと呼ばれます。

正規表現オブジェクトを動的に割り当て、それらへのポインターをクラスに格納する必要があります。スマートポインターをお勧めします。継承階層の代わりに、クラスに格納されている正規表現オブジェクトのタイプ、テンプレート パラメーターを作成することもできます。これはおそらく実装が難しく、いくつかの欠点があります。

于 2013-09-11T16:21:15.740 に答える