|
Boost Users : |
From: todd (todd_at_[hidden])
Date: 2004-02-08 13:18:16
On Sun, 08 Feb 2004 20:47:41 +0000, Steve Folly wrote
> Hmmm... I've looked at our other posts in this thread and I don't
> think I've really explained my problem:
Actually, I think you explained the problem quite well.
> I initially wanted to use shared pointers to not have to worry about
> memory deallocation.
Yes. All smart pointers serve this purpose.
> [please ignore syntax errors!]
ditto.
class statement: public ref_counted
{
public:
virtual void execute() = 0;
};
typedef intrusive_ptr<statement> statement_p;
// Look at this trick :)
typedef intrusive_ptr<class block_statement> block_statement_p;
class block_statement : public statement
{
public:
block_statement ();
block_statement_p add( statement_p s )
{
statements.push_back( s );
return this; // conversion is implicit
}
private:
std::list<statement_p> statements;
};
typedef intrusive_ptr<class if_statement> if_statement_p;
class if_statement : public statement
{
public:
if_statement ( expression_p );
if_statement_p then_( statement_p s )
{
then_statement = s;
return this;
}
if_statement_p else_( statement_p s )
{
else_statement = s;
return this;
}
private:
statement_p then_statement;
statement_p else_statement;
};
// helper functions
block_statement_p block_()
{
return new block_statement(); // conversion is implicit
}
if_statement_p if_( expression_p e )
{
return new if_statement( e ); // conversion is implicit
}
// same as what you had...
block_p b = block_()
->add(
if_( expression )
->then( stmt2 )
->else( stmt3 )
)
->add(
if_( expression )
->then( stmt2 )
->else( stmt3 )
);
> My dilemma is - what do block_statement::add, if_statement::then and
> if_statement::else return? Since they have no knowledge of the shared
> pointer, the best they can do is to return 'this', but block_statement::add
> is expecting the shared pointer?
intrusive_ptr can be declared on a class that hasn't been defined yet. The
functions shoud return an intrusive_ptr. I think I said earlier that they
could return normal pointers; if so I made a mistake. That *might* cause
premature deletion; the standard doesn't place a strong enough guarantee on
the order of operations. i.e. a temporary intrusive_ptr might be destructed
before another is constructed if those member functions return normal pointers.
The call to add() in the example above automatically converts the
intrusive_ptr<if_statement> to an intrusive_ptr<statement>; shared_ptr can't
do that. This assumes that you are using a recent compiler.
A caveat: don't be tempted to do the following, now that you know about the
implicit conversions:
block_p b = (new block_statement)
->add(
(new if_statement( expression ) )
->then( stmt2 )
->else( stmt3 )
)
->add(
( new if_statement( expression ) )
->then( stmt2 )
->else( stmt3 )
);
It will compile and run, but it may leak memory if an exception is thrown.
Todd
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net