Expression
たとえば、ブール式のような式を表す再帰クラスがあります。
(a & b) | (c & ~d)
Expression
が単項式と 2 項式の両方を処理することに注意してください。基本的にExpression
、ブール式と同様に CFG に従う必要があります。
私はこのようにクラスを設計しました:
class Expression {
public:
Expression() = default;
Expression(unique_ptr<Expression> lhs, unique_ptr<Expression> rhs,
unique_ptr<IBinaryOperator> binop, unique_ptr<IUnaryOperator> unop);
Expression operator^(Expression& that);
Expression operator%(Expression& that);
Expression operator|(Expression& that);
Expression operator*(Expression& that);
Expression operator+(Expression& that);
Expression operator&(Expression& that);
Expression operator>>(Expression& that);
Expression operator!();
Expression operator~();
double Evaluate(double x);
virtual ~Expression();
protected:
unique_ptr<Expression> _lhs = nullptr;
unique_ptr<Expression> _rhs = nullptr;
unique_ptr<IBinaryOperator> _binop = nullptr;
unique_ptr<IUnaryOperator> _unop = nullptr;
};
コンストラクターの実装と、二項演算子と単項演算子のそれぞれ 1 つを以下に示します。
Expression::Expression(unique_ptr<Expression> lhs, unique_ptr<Expression> rhs, unique_ptr<IBinaryOperator> binop, unique_ptr<IUnaryOperator> unop) :
_lhs(move(lhs)), _rhs(move(rhs)), _binop(move(binop)), _unop(move(unop)) {
}
Expression Expression::operator+(Expression&& that) {
return Expression(unique_ptr<Expression>(this), unique_ptr<Expression>(&that), unique_ptr<IBinaryOperator>(new SumCoNorm), nullptr);
}
Expression Expression::operator~() {
return Expression(nullptr, unique_ptr<Expression>(this), nullptr, unique_ptr<IUnaryOperator>(new Intensify));
}
クラスはコンパイルに失敗します
error: use of deleted function 'Fuzzy::Expression::Expression(const Fuzzy::Expression&)'
オーバーロードされた各演算子 (return ステートメント内)。一部の関数が、存在しない unique_ptr のコピー コンストラクターを内部的に使用しようとしているように感じます。ポインターをあちこちに移動すると何か問題がありますか? GCCv4.8 で C++11 を使用しています。
何らかの方法でクラス インターフェイスの変更を提案することは大歓迎です。生のポインターの使用は避けたいと思います。
注: Boost.Spirit、YARD、YACC などのパーサー ジェネレーターなどの使用を提案しないでください。アプリケーションでは、これを最初から実装する必要があります。