Calling Dtor at the End of a Class Method

V

Volkan YAZICI

Hi,

I have a class hierarchy as follows:

class InternalRow {
public:
virtual int get() const = 0;
virtual void set() = 0;
};

class PhysicalRow: public InternalRow {
public:
int get() const;
void set();
};

class VirtualRow: public InternalRow {
public:
int get() const;
void set();
};

class Row: public InternalRow {
public:
int get();
void set();
private:
InternalRow *row;
};

User is interfaced to the rows through Row class. And Row redirects
get/set calls to the related InternalRow implementation pointed by
Row::row field. There are two InternalRow implementations: 1)
PhysicalRow, which holds actual data, 2) VirtualRow, which holds a
reference to some PysicalRow. VirtualRow redirects get methods asis to
the related PhysicalRow. But when a set() call is made on a
ReferenceRow, I'd like that ReferenceRow to get upgraded to a
PhysicalRow. For this purpose, I replaced "void set()" methods with
"InternalRow* set()" methods, and call set() methods in Row as "row =
row->set()". To summarize, new design becomes something like this:

class InternalRow {
public:
virtual int get() const = 0;
virtual InternalRow* set() = 0;
};

class PhysicalRow: public InternalRow {
public:
int get() const;
InternalRow* set();
};

class VirtualRow: public InternalRow {
public:
int get() const;
InternalRow* set() {
return (new PhysicalRow())->set();
}
};

class Row: public InternalRow {
public:
int get();
void set() { row = row->set(); }
private:
InternalRow *row;
};

But here, the caller ReferenceRow instance should be free'd just after
returning (new PhysicalRow())->set(). How can I call the dtor at the
end of ReferenceRow::set() calls? Do you suggest a different approach?
What are your ideas?


Best.
 
R

Ruben Safir

Volkan YAZICI said:
Hi,

I have a class hierarchy as follows:

class InternalRow {
public:
virtual int get() const = 0;
virtual void set() = 0;
};

class PhysicalRow: public InternalRow {
public:
int get() const;
void set();
};

class VirtualRow: public InternalRow {
public:
int get() const;
void set();
};

class Row: public InternalRow {
public:
int get();
void set();
private:
InternalRow *row;
};

User is interfaced to the rows through Row class. And Row redirects
get/set calls to the related InternalRow implementation pointed by
Row::row field. There are two InternalRow implementations: 1)
PhysicalRow, which holds actual data, 2) VirtualRow, which holds a
reference to some PysicalRow. VirtualRow redirects get methods asis to
the related PhysicalRow. But when a set() call is made on a
ReferenceRow, I'd like that ReferenceRow to get upgraded to a
PhysicalRow. For this purpose, I replaced "void set()" methods with
"InternalRow* set()" methods, and call set() methods in Row as "row =
row->set()". To summarize, new design becomes something like this:

class InternalRow {
public:
virtual int get() const = 0;
virtual InternalRow* set() = 0;
};

class PhysicalRow: public InternalRow {
public:
int get() const;
InternalRow* set();
};

class VirtualRow: public InternalRow {
public:
int get() const;
InternalRow* set() {
return (new PhysicalRow())->set();
}
};

class Row: public InternalRow {
public:
int get();
void set() { row = row->set(); }
private:
InternalRow *row;
};

But here, the caller ReferenceRow instance should be free'd just after
returning (new PhysicalRow())->set(). How can I call the dtor at the
end of ReferenceRow::set() calls? Do you suggest a different approach?
What are your ideas?


Best.


vecotrs or lists of type row
 
V

Volkan YAZICI

vecotrs or lists of type row

Excuse me, but I couldn't understand what does this have to do with
the above dtor call problem. Can you elaborate your suggestion,
please? (Surely, I'll store a vector/list of "Row"s, but I need
ReferenceRow to save from space and avoid unnecessary duplication.)


Best.
 
H

Haitham Gad

One easy way I think of, but don't really like, is:

void Row::set() {
InternalRow* temp = row;
row = row->set();
if (dynamic_cast<VirtualRow*>(temp)) {
delete temp;
}
}

Try taking a look at the Proxy design pattern. I think it address a
similar problem to yours.

Haitham
 
Ö

Öö Tiib

[... snip totally confusing code ...]
User is interfaced to the rows through Row class. And Row redirects
get/set calls to the related InternalRow implementation pointed by
Row::row field. There are two InternalRow implementations: 1)
PhysicalRow, which holds actual data, 2) VirtualRow, which holds a
reference to some PysicalRow. VirtualRow redirects get methods asis to
the related PhysicalRow. But when a set() call is made on a
ReferenceRow, I'd like that ReferenceRow to get upgraded to a
PhysicalRow. For this purpose, I replaced "void set()" methods with
"InternalRow* set()" methods, and call set() methods in Row as "row =
row->set()".

[... snip totally confusing code ...]
But here, the caller ReferenceRow instance should be free'd just after
returning (new PhysicalRow())->set(). How can I call the dtor at the
end of ReferenceRow::set() calls? Do you suggest a different approach?
What are your ideas?

Your reference row or virtual row (or what it was?) looks like
shared_ptr<PhysicalRow>. What you seemingly want to achieve is copy-on-
write. That is however most easy to achieve with pimpl idiom. Also you
add inheritance for some unknown reason. So your design seems to
result with confused mix of these three things and numerous rather
empty classes that do nothing but forward each other endlessly. Start
by implementing one thing that looks like a class:

// Row.h
class Row
{
public:
Row();
~Row();
Row(Row const&);
Row& operator=(Row const&);
int get() const;
void set();
private:
class InternalRow;
InternalRow* pimpl;
};

That is the only thing that user will see. Rest of your logic hide
into Row.cpp.

If you need to refcount, refcount intrusively in IntrnalRow, if you
need to copy on write in set() then copy object behind pimpl and
assign copy to pimpl. If you need whole cascade of InternalRow-derived
classes then go ahead (inside Row.cpp), but don't derive class Row
from it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top