2

クラス Plus は、クラス Expression を継承します。

class Expression
{
 public:
  virtual Expression* clone() const = 0;
};
class Plus : public Expression
{
 public:
 Plus( Expression* lhs, Expression* rhs ) :Expression( lhs, rhs) {};
 Plus* clone() const;
};

機能を実装していcopyます。cloneのいずれかまたは が失敗した場合、現在の実装ではメモリ リークが発生しPlusます。

Plus* Plus::clone() const  {
        return new Plus(tree_left->clone(), tree_right->clone());
}

そして、このようなものが問題を解決すると思います:

Plus* Plus::clone() const  {
        Expression *tree_left_clone = nullptr;
        Expression *tree_right_clone = nullptr;
        Expression *plus_clone = nullptr;
        try {
             tree_left_clone = tree_left->clone();
             tree_right_clone = tree_right->clone()
             plus_clone = new Plus( tree_left_clone, tree_right_clone );
        } catch (const bad_alloc& e ) {
             delete tree_left_clone;
             delete tree_right_clone;
             delete plus_clone;
        }
        return plus_clone;
}

しかし、Minus、Times、Divided、Power など、似たような演算子がたくさんありcloneます。それらすべてを複製する必要があります。このコードを に入れる方法はありExpressionますか? 私が抱えている問題は、cloneを含む行にありnew Plusます。

4

3 に答える 3

1

それがスマートポインターの目的です。コンストラクターを変更して、次を受け取ることができますstd::unique_ptr

Plus( std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs )
  : Expression( lhs.release(), rhs.release() ) {}

次のように呼び出します。

Plus* Plus::clone() const {
    std::unique_ptr<Expression> lhs( tree_left->clone() );
    std::unique_ptr<Expression> rhs( tree_right->clone() );
    return new Plus( std::move(lhs), std::move(rhs) );
}

しかし、それは始まりにすぎません。また、ポインタをそのまま保存することを検討しstd::unique_ptr、プレーンなポインタをできるだけ避ける必要があります。

于 2013-11-06T22:06:01.510 に答える