Boost logo

Boost Users :

From: Steve Folly (boost_at_[hidden])
Date: 2004-02-08 15:47:41


On 7/2/04 9:37 pm, in article 20040207213053.M73385_at_[hidden],
"todd" <todd_at_[hidden]> wrote:

> On Sun, 08 Feb 2004 01:28:38 +0000, Steve Folly wrote
>> The problem is to be able to chain then_ and else_ together, I have
>> to return a plain pointer because the if_ statement itself doesn't
>> know about it's shared pointer. So now, the compiler complains that
>> can't implicitly convert a plain if_statement pointer into a shared
>> pointer. And even if it could, I don't have the original shared
>> pointer to hand.
>
> It looks like you can solve this by using intrusive pointers instead of shared
> pointers. The compiler can implicitly convert normal pointers into intrusive
> ones.
>
> Todd

Hmmm... I've looked at our other posts in this thread and I don't think I've
really explained my problem:

I initially wanted to use shared pointers to not have to worry about memory
deallocation.

[please ignore syntax errors!]

class statement
{
public:
    virtual void execute() = 0;
};

typedef shared_ptr<statement> statement_p;

class block_statement : public statement
{
public:
    block_statement ();
    block_statement_p add( statement_p s )
    {
        statements.push_back( s );
        return ????;
    }

private:
    std::list<statement_p> statements;
};

typedef shared_ptr<block_statement> block_statement_p;

class if_statement : public statement
{
public:
    if_statement ( expression_p );

    if_statement_p then_( statement_p s )
    {
        then_statement = s;
        return ????;
    }

    if_statement_p else_( statement_p s )
    {
        else_statement = s;
        return ????;
    }

private:
    statement_p then_statement;
    statement_p else_statement;
};

typedef shared_ptr<if_statement> if_statement_p;

// helper functions

block_statement_p block_()
{
    return block_statement_p( new block_statement() );
}

if_statement_p if_( expression_p e )
{
    return if_statement_p( new if_statement( e ) );
}

So... To construct a block containing two if statements:

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?

One solution I'm considering is to do away with the shared pointers as
parameters, but keep them internal to the classes (then_statement,
else_statement, and block_statement::statements).

The intent isn't to share statements between different parts of the script,
for example creating a single if statement and inserting it into 2 different
blocks.

So perhaps block_statement::add should be:

    block_statement* add( statement* s )
    {
        statements.push_back( statement_p( s ) );
        return this;
    }

and the helper function becomes

    block_statement* block_()
    {
        return new block_statement();
    }

Ok, there is *some* danger of duplicated pointers, but I can live with that
it it's well documented. It would also makes the syntax (and implementation)
nicer!

Steve.


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