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如果s 或 s之一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 回答
1

尝试这样的事情:

    Plus* Plus::clone() const  {
         auto_ptr<Expression> tree_left_clone(tree_left->clone());
         auto_ptr<Expression> tree_right_clone(tree_right->clone());
         return new Plus(tree_left_clone.release(), tree_right_clone.release());
    }
于 2013-11-06T22:03:26.473 回答
1

使用智能指针而不是原始指针,您的代码不会泄漏:

class Expression;
typedef std::shared_ptr<Expression> ExpressionPtr;
class Expression
{
 public:
  virtual ExpressionPtr clone() const = 0;
};
class Plus : public Expression
{
 public:
 Plus( ExpressionPtr lhs, ExpressionPtr rhs ) :Expression( lhs, rhs) {};
 ExpressionPtr clone() const;
};

ExpressionPtr Plus::clone() const  {
    return std::make_shared<Plus>( tree_left->clone(), tree_right->clone() );
}

如果 c++11 不可用,您可以使用 boost::shared_ptr。

于 2013-11-06T22:03:43.897 回答