Class 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
的行。
答案 0 :(得分: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());
}
答案 1 :(得分: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。
答案 2 :(得分: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
,并尽可能避免使用普通指针。