473,804 Members | 2,202 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

delete a composite

This question is a little embarrassing... I have a boolean expressions
interpreter with its composite (see Go4's "Design Patterns" book).
here is a simple leaf of the composite:

class Constant : public BooleanExp {
public:
Constant(bool);
virtual ~Constant();
virtual void Accept(BooleanE xpVisitor&);

bool GetValue() const {return _value;}

private:
bool _value;
};

and here is a composite complying with the BooleanExp interface:

class AndExp : public BooleanExp {
public:
AndExp(BooleanE xp*, BooleanExp*);
virtual ~AndExp();
virtual void Accept(BooleanE xpVisitor&);

private:
BooleanExp* _operand1;
BooleanExp* _operand2;
};

Consider a few other classes that are similar in concept, including
OrExp, VariableExp and so on. The Context class maps variables to
their boolean values.
Now I want to evaluate an expression:

BooleanExp *expression;
Context cont;

context.Assign( x, false);
context.Assign( y, true);

EvaluationVisit or visitor(cont);

expression = new OrExp (
new AndExp (new Constant (true), x),
new AndExp (y, new NotExp (x))
);

bool result = expression->Accept(visitor );

Up to here everything is good. My question is, how do I collect the
garbage?
What I have at the moment is

delete expression;

Do you think this will do?
I have a virtual destructor for each of the BooleanExp (concrete)
subclasses, and they all do nothing. Correct me if I'm wrong, but I
don't think it's a good idea to let these destructors have the
responsibility to clean up since the dynamic allocations are performed
out of the class.

TIA,

Matan Nassau
Jul 22 '05 #1
4 1441

"Matan Nassau" <Fo************ @ICQMail.com> wrote in message
news:3c******** *************** ***@posting.goo gle.com...
This question is a little embarrassing... I have a boolean expressions
interpreter with its composite (see Go4's "Design Patterns" book).
here is a simple leaf of the composite:

class Constant : public BooleanExp {
public:
Constant(bool);
virtual ~Constant();
virtual void Accept(BooleanE xpVisitor&);

bool GetValue() const {return _value;}

private:
bool _value;
};

and here is a composite complying with the BooleanExp interface:

class AndExp : public BooleanExp {
public:
AndExp(BooleanE xp*, BooleanExp*);
virtual ~AndExp();
virtual void Accept(BooleanE xpVisitor&);

private:
BooleanExp* _operand1;
BooleanExp* _operand2;
};

Consider a few other classes that are similar in concept, including
OrExp, VariableExp and so on. The Context class maps variables to
their boolean values.
Now I want to evaluate an expression:

BooleanExp *expression;
Context cont;

context.Assign( x, false);
context.Assign( y, true);

EvaluationVisit or visitor(cont);

expression = new OrExp (
new AndExp (new Constant (true), x),
new AndExp (y, new NotExp (x))
);

bool result = expression->Accept(visitor );

Up to here everything is good. My question is, how do I collect the
garbage?
What I have at the moment is

delete expression;

Do you think this will do?
It won't free the allocated memory.
I have a virtual destructor for each of the BooleanExp (concrete)
subclasses, and they all do nothing. Correct me if I'm wrong, but I
don't think it's a good idea to let these destructors have the
responsibility to clean up since the dynamic allocations are performed
out of the class.


It's quite common for classes to 'take ownership' of pointers in this way.
It's the basis of most smart pointer classes for instance. I would do the
deletes in the destructors, anything else is going to be very tedious and
therefore very error prone.

john
Jul 22 '05 #2
Matan Nassau wrote:
This question is a little embarrassing... I have a boolean expressions
interpreter with its composite (see Go4's "Design Patterns" book).
here is a simple leaf of the composite:

class Constant : public BooleanExp {
public:
Constant(bool);
virtual ~Constant();
virtual void Accept(BooleanE xpVisitor&);

bool GetValue() const {return _value;}

private:
bool _value;
};

and here is a composite complying with the BooleanExp interface:

class AndExp : public BooleanExp {
public:
AndExp(BooleanE xp*, BooleanExp*);
virtual ~AndExp();
virtual void Accept(BooleanE xpVisitor&);

private:
BooleanExp* _operand1;
BooleanExp* _operand2;
};

Consider a few other classes that are similar in concept, including
OrExp, VariableExp and so on. The Context class maps variables to
their boolean values.
Now I want to evaluate an expression:

BooleanExp *expression;
Context cont;

context.Assign( x, false);
context.Assign( y, true);

EvaluationVisit or visitor(cont);

expression = new OrExp (
new AndExp (new Constant (true), x),
new AndExp (y, new NotExp (x))
);

bool result = expression->Accept(visitor );

Up to here everything is good. My question is, how do I collect the
garbage?
It depends on who [you think] owns those pointers. The owner should
dispose of them. There is no "garbage collection", everybody disposes of
their own rubbish.
What I have at the moment is

delete expression;

Do you think this will do?
How should we know? You posted no implementation of your classes. Does
'AndExp' own the object, to which pointers 'operand_1' and 'operand_2'
point? If so, it should dispose of them in the destructor.
I have a virtual destructor for each of the BooleanExp (concrete)
subclasses, and they all do nothing. Correct me if I'm wrong, but I
don't think it's a good idea to let these destructors have the
responsibility to clean up since the dynamic allocations are performed
out of the class.


Dynamic allocations for std::auto_ptr are performed "out of the class" but
it doesn't prevent std::auto_ptr from being responsible of disposing the
object. It all depends on what responsibilitie s you assign to your classes.

Don't forget to document them.

Victor
Jul 22 '05 #3
WT
Thank you very much, Victor, and you, John, for your fast replies.
delete expression;

Do you think this will do?
How should we know? You posted no implementation of your classes. Does
'AndExp' own the object, to which pointers 'operand_1' and 'operand_2'
point? If so, it should dispose of them in the destructor.


I posted the implementations that I thought were important for the question,
and I ommited others.
OrExp is realy similar to AndExp. I could actually say that the two are
identical, and the only difference in behavior is actually in the visitor,
which ORs the two operands instead of ANDs them when OrExp accepts the
visit.
Here is the Accept operation of OrExp:

void OrExp::Accept(B ooleanExpVisito r &visitor)
{
_operand1->Accept(visitor );
_operand2->Accept(visitor );
visitor.VisitOr Exp(this);
}

The visitor class should be provided as well, I apologize.

class EvaluationVisit or : public BooleanExpVisit or {
public:
EvaluationVisit or(Context&);
~EvaluationVisi tor();
bool PopResult();
virtual void VisitVariableEx p(VariableExp*) ;
virtual void VisitConstant(C onstant*);
virtual void VisitAndExp(And Exp*);
virtual void VisitOrExp(OrEx p*);
virtual void VisitNotExp(Not Exp*);
private:
Context& _context;
deque <bool> _result;
};

The class complies with the BooleanExpVisit or interface. it overrides its
defaults. PopResult pops the last result out of the _result stack.
Here's VisitOrExp:

void EvaluationVisit or::VisitOrExp( OrExp *exp)
{
if (_result.empty( ))
throw false;
// pop, pop, evaluate and push
bool val2 = _result.back();
_result.pop_bac k();
bool val1 = _result.back();
_result.pop_bac k();
_result.push_ba ck( val1 || val2 );
}

VisitVariableEx p will find the value of the variable in the context map,
which is a member of the visitor, and will push it into the stack.
VisitConstant will get the constant value and push it into the stack.
NotExp is the same class as OrExp and AndExp with one operand instead of 2,
and another difference in the visitor which NOTs the operand of the NotExp
object.
Constant is a leaf similar to VariableExp, with the 2 differences similiar
to those above: a bool member variable which holds its value, instead of a
char* which holds the variable's name.
Context maps variable names to their boolean values, and it is useful to
change the result of an expression without changing the expression. It has
the following interface:

class Context {
public:
bool Lookup(const char*) const;
void Assign(Variable Exp*, bool);
private:
map<const char*, bool> _theMap;
};

I think the interface speaks for itself. It's pretty much a wrapper for the
map, only providing just the necessary manipulation methods.
Dynamic allocations for std::auto_ptr are performed "out of the class" but
it doesn't prevent std::auto_ptr from being responsible of disposing the
object.
That's also what John said. But I think this is because that is exactly the
idea behind smart pointers: take over the responsibility of cleaning up, and
do it safely. What I was hesitating about, was what you mentioned next:
It all depends on what responsibilitie s you assign to your classes.
my classes don't have to help the client with anything other than
interpreting boolean expressions. if they make a mess, ofcourse they must
clean after. However, at the moment it's the client which allocates the
objects that construct the composite. I could go John's way, and delete
everything in the the constructors, at the price of safety (any other price
I'm unaware of?). Or I could go with the more "apathetic" attitude, allowing
the client to allocate objects - but not cleaning up after it. I think it
realy is a matter of opinion, and there is no strict answer to that...
Don't forget to document them.


Good practice is what I'm practicing. Documentation is a good practice
indeed.

Matan
Jul 22 '05 #4
Thank you very much, Victor, and you, John, for your fast replies.
delete expression;

Do you think this will do?
How should we know? You posted no implementation of your classes. Does
'AndExp' own the object, to which pointers 'operand_1' and 'operand_2'
point? If so, it should dispose of them in the destructor.


I posted the implementations that I thought were important for the question,
and I ommited others.
OrExp is realy similar to AndExp. I could actually say that the two are
identical, and the only difference in behavior is actually in the visitor,
which ORs the two operands instead of ANDs them when OrExp accepts the
visit.
Here is the Accept operation of OrExp:

void OrExp::Accept(B ooleanExpVisito r &visitor)
{
_operand1->Accept(visitor );
_operand2->Accept(visitor );
visitor.VisitOr Exp(this);
}

The visitor class should be provided as well, I apologize.

class EvaluationVisit or : public BooleanExpVisit or {
public:
EvaluationVisit or(Context&);
~EvaluationVisi tor();
bool PopResult();
virtual void VisitVariableEx p(VariableExp*) ;
virtual void VisitConstant(C onstant*);
virtual void VisitAndExp(And Exp*);
virtual void VisitOrExp(OrEx p*);
virtual void VisitNotExp(Not Exp*);
private:
Context& _context;
deque <bool> _result;
};

The class complies with the BooleanExpVisit or interface. it overrides its
defaults. PopResult pops the last result out of the _result stack.
Here's VisitOrExp:

void EvaluationVisit or::VisitOrExp( OrExp *exp)
{
if (_result.empty( ))
throw false;
// pop, pop, evaluate and push
bool val2 = _result.back();
_result.pop_bac k();
bool val1 = _result.back();
_result.pop_bac k();
_result.push_ba ck( val1 || val2 );
}

VisitVariableEx p will find the value of the variable in the context map,
which is a member of the visitor, and will push it into the stack.
VisitConstant will get the constant value and push it into the stack.
NotExp is the same class as OrExp and AndExp with one operand instead of 2,
and another difference in the visitor which NOTs the operand of the NotExp
object.
Constant is a leaf similar to VariableExp, with the 2 differences similiar
to those above: a bool member variable which holds its value, instead of a
char* which holds the variable's name.
Context maps variable names to their boolean values, and it is useful to
change the result of an expression without changing the expression. It has
the following interface:

class Context {
public:
bool Lookup(const char*) const;
void Assign(Variable Exp*, bool);
private:
map<const char*, bool> _theMap;
};

I think the interface speaks for itself. It's pretty much a wrapper for the
map, only providing just the necessary manipulation methods.
Dynamic allocations for std::auto_ptr are performed "out of the class" but
it doesn't prevent std::auto_ptr from being responsible of disposing the
object.
That's also what John said. But I think this is because that is exactly the
idea behind smart pointers: take over the responsibility of cleaning up, and
do it safely. What I was hesitating about, was what you mentioned next:
It all depends on what responsibilitie s you assign to your classes.
my classes don't have to help the client with anything other than
interpreting boolean expressions. if they make a mess, ofcourse they must
clean after. However, at the moment it's the client which allocates the
objects that construct the composite. I could go John's way, and delete
everything in the the constructors, at the price of safety (any other price
I'm unaware of?). Or I could go with the more "apathetic" attitude, allowing
the client to allocate objects - but not cleaning up after it. I think it
realy is a matter of opinion, and there is no strict answer to that...
Don't forget to document them.


Good practice is what I'm practicing. Documentation is a good practice
indeed.

Matan
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
10810
by: Patrizio | last post by:
Hi All, I've the following table with a PK defined on an IDENTITY column (INSERT_SEQ): CREATE TABLE MYDATA ( MID NUMERIC(19,0) NOT NULL, MYVALUE FLOAT NOT NULL, TIMEKEY INTEGER NOT NULL, TIMEKEY_DTTM DATETIME NULL,
3
2423
by: Alexander Anderson | last post by:
I have a DELETE statement that deletes duplicate data from a table. It takes a long time to execute, so I thought I'd seek advice here. The structure of the table is little funny. The following is NOT the table, but the representation of the data in the table: +-----------+ | a | b | +-----+-----+ | 123 | 234 | | 345 | 456 |
6
2434
by: Matan Nassau | last post by:
Hello. i have a composite which i want to delete. this is a composite which represents a boolean expression (see a previous post of mine with more details at http://groups.google.ca/groups?hl=en&lr=&ie=UTF-8&threadm=AXqqc.89218%24PJ1.865449%40wagner.videotron.net&rnum=1&prev=/groups%3Fq%3Dmatan%2Bnassau%26hl%3Den%26lr%3D%26ie%3DUTF-8%26sa%3DG%26scoring%3Dd ) VariableExp *x = new VariableExp("X"); VariableExp *y = new VariableExp("Y");...
0
2405
by: AshifToday | last post by:
this was my and my frineds little project in earlier classes, the program seperates the composite and prime numbers in two sections of the screen ===================== /* This program has been made by A & A Group. Muhammad Ali: Roll # 1462 Class A-2 , B.Sc.(Hons.) in C.S.
2
4994
by: ms | last post by:
Access 2000: I am trying to delete duplicate records imported to a staging table leaving one of the duplicates to be imported into the live table. A unique record is based on a composite key of 3 fields (vehicleID, BattID, and ChgHrs). VehicleID and BattID are a TEXT datatype and ChrHrs are a number(long int.) datatype. Since records to be imported can have duplicate records of the composite key I need to clean all but one of the...
18
12669
by: Thomas A. Anderson | last post by:
I am a bit confused in creating a composite primary key. I have three table with two of the tables containing primary keys. I have two of the tables (each with a primary key) having one to many relations with the table containing no primary key. Do I just create two primary keys on the table that does not contain any primary key for this to become a composite primary key? Thank you in advance! Still a newbie,
4
4059
by: Ismail Rajput | last post by:
Is there any option we can use Composite DataKeyField in the DataList and DataGrid?
14
5041
by: dave.dolan | last post by:
Basically I'd like to implement the composite design pattern with leaves that are either of reference or value types, but even using generics I can't seem to avoid boxing (using ArrayList or Object) Is this even possible, or is the composite pattern doomed to use the System.Object type forever? I have tried using interfaces with generics, but I always stumble on the Value property (when trying to return the value of a particular node)
2
3513
by: lfhenry | last post by:
Hi All, I am about to make some changes to a process we have. The new process will have a new table who's job it is to store temporarily data such as customer, clerkno,productno, storeno , amount, time. On a new request from a front-end i will select against the primary keys to ensure no other request for the same data has been made. This is then sent to a backend system asynchronously if there is no match. I will otherwise send a...
0
9715
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10600
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10354
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9175
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7642
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6867
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5673
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3835
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3002
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.