Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Return object without exposing it to delete

Reply
Thread Tools

Return object without exposing it to delete

 
 
Pete Becker
Guest
Posts: n/a
 
      01-26-2007
Michael Pradel wrote:
>
> That's one of the examples why I am looking for a general way to
> distinguish the case where the using class may delete the returned
> object and the case where it shouldn't.
>


Document what the rules are. It's not your job to force other progammers
to be competent.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
Reply With Quote
 
 
 
 
Daniel T.
Guest
Posts: n/a
 
      01-26-2007
Michael Pradel <(E-Mail Removed)> wrote:

> > By simply observing a simple rule: the code responsible for allocating
> > an object is also solely responsible for that object's deallocation.

>
> That's a good solution for most of the cases, but e.g. using the Factory
> Method design pattern it doesn't make sense.


The rule also doesn't make sense for a system that makes extensive use
of smart pointers (most of which do delete objects but don't create
them.)

Just document who is in charge of deleting what and you will be fine.
It's the C++ way.
 
Reply With Quote
 
 
 
 
Clark S. Cox III
Guest
Posts: n/a
 
      01-26-2007
Michael Pradel wrote:
>> By simply observing a simple rule: the code responsible for allocating
>> an object is also solely responsible for that object's deallocation.

>
> That's a good solution for most of the cases, but e.g. using the Factory
> Method design pattern it doesn't make sense. Here one class is only
> responsible for creating the object while another will use it and knowns
> when to delete it.
>
> Product* Factory::create(ProductID id) {
> if (id == A) return new ProductA;
> // ...
> }
>
> That's one of the examples why I am looking for a general way to
> distinguish the case where the using class may delete the returned
> object and the case where it shouldn't.


Outside of establishing a set of rules, documenting them, and expecting
others to follow them, there is no general way to distinguish the two cases.

--
Clark S. Cox III
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Roland Pibinger
Guest
Posts: n/a
 
      01-26-2007
On Fri, 26 Jan 2007 20:26:44 +0100, Michael Pradel wrote:
>> By simply observing a simple rule: the code responsible for allocating
>> an object is also solely responsible for that object's deallocation.

>
>That's a good solution for most of the cases, but e.g. using the Factory
> Method design pattern it doesn't make sense.


only when you use F.M. like Gamma et al.

>Here one class is only
>responsible for creating the object while another will use it and knowns
>when to delete it.


It makes perfect sense when the factory remains the owner of the
created objets. This is called the "Creator as Sole Owner" pattern.
See: http://www.ddj.com/184409895 and
http://www.artima.com/intv/modern3.html

Best wishes,
Roland Pibinger
 
Reply With Quote
 
kwikius
Guest
Posts: n/a
 
      01-26-2007


On 26 Jan, 16:51, Michael Pradel <(E-Mail Removed)> wrote:
> Hi all,
>
> I just returned to C++ after programming in other languages, and find
> myself a bit puzzled about the following issue: (see attached code).
>
> How can I avoid the deletion of an object that is returned by a method?
> Is returning a clone of it the only possibility? That would use a lot of
> memory in case of larger objects.
>
> Thanks a lot!
>
> Michael
>
> #include <iostream>
> using namespace std;
>
> class Dummy {
> public:
> int n;
>
> };class Victim {
> private:
> Dummy *d;
>
> public:
> Victim() {
> d = new Dummy();
> d->n = 23;
> }
>
> Dummy* getDummy() {
> return d;
> }
>
> };int main(int argc, char **argv) {
> Victim *v = new Victim();
> Dummy *d = v->getDummy();
>
> cout << d->n << endl;
> delete d;
> cout << d->n << endl;


Can also make destructor of object private. In code below pointer is
nullified by delete_and clean. raw delete won't compile. Of course
creating stack objects will fail too..


#include <iostream>

template <typename T>
inline
void delete_and_clean ( T* & rp)
{
delete rp;
rp =0;
}

struct my{
int n;
my():n(42){}

private:
friend void delete_and_clean<my> ( my* & );
~my(){}
};

int main()
{
my * p = new my;

if ( p ){
std::cout << p->n << '\n';
}

//compile fail due to private dtor
// delete p;

delete_and_clean(p);

if ( p ){
std::cout << "Bad news : " << p->n << '\n';
}
else {
std::cout << "p died\n";
}

}

 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      01-27-2007
"kwikius" <(E-Mail Removed)> wrote:

> Can also make destructor of object private. In code below pointer is
> nullified by delete_and clean. raw delete won't compile. Of course
> creating stack objects will fail too..
>
>
> #include <iostream>
>
> template <typename T>
> inline
> void delete_and_clean ( T* & rp)
> {
> delete rp;
> rp =0;
> }
>
> struct my{
> int n;
> my():n(42){}
>
> private:
> friend void delete_and_clean<my> ( my* & );
> ~my(){}
> };
>
> int main()
> {
> my * p = new my;
>
> if ( p ){
> std::cout << p->n << '\n';
> }
>
> //compile fail due to private dtor
> // delete p;
>
> delete_and_clean(p);
>
> if ( p ){
> std::cout << "Bad news : " << p->n << '\n';
> }
> else {
> std::cout << "p died\n";
> }
>
> }


But anyone who has access to delete_and_clean can delete the object, so
that doesn't restrict access...

You could make op& private and not implement it. Then the only parts of
the code that can delete the object will be those that have a pointer to
it. Then restrict who has a pointer to the object (other code only gets
references to the object.) Of course, then you won't be able to put the
object in any standard containers.

Another idea is to wrap the object in a smart pointer that doesn't
implement op*() [it only implements op->()]. But then the caller will be
unable to pass the object to something that requires a reference.

Frankly, I think any solution would cause more problems than it solves.
Just document ownership, that's all you can do.
 
Reply With Quote
 
AndrewD
Guest
Posts: n/a
 
      01-27-2007
Michael,

Make Dummy destructor private and class Victim a friend as follows:

class Dummy {
public:
int n;
private:
~Dummy() {}
friend class Victim;
};

The compiler will reject the delete code in main() with something
like:
F:\dummy\dummy.cpp(3 : error C2248: 'Dummy::~Dummy' : cannot access
private member declared in class 'Dummy'
but will allow delete of Dummy's by Victim.

....AndrewD...




 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      01-27-2007
"AndrewD" <(E-Mail Removed)> wrote:

> Michael,
>
> Make Dummy destructor private and class Victim a friend as follows:
>
> class Dummy {
> public:
> int n;
> private:
> ~Dummy() {}
> friend class Victim;
> };


Now Dummy can't be created by any other class than Victim. That's a
rather draconian restriction just to safe-guard some data from delete.
 
Reply With Quote
 
Dave Rahardja
Guest
Posts: n/a
 
      01-27-2007
On Sat, 27 Jan 2007 17:00:50 GMT, "Daniel T." <(E-Mail Removed)> wrote:

>"AndrewD" <(E-Mail Removed)> wrote:
>
>> Michael,
>>
>> Make Dummy destructor private and class Victim a friend as follows:
>>
>> class Dummy {
>> public:
>> int n;
>> private:
>> ~Dummy() {}
>> friend class Victim;
>> };

>
>Now Dummy can't be created by any other class than Victim. That's a
>rather draconian restriction just to safe-guard some data from delete.


How's that? The default constructor is still public. Anyone can construct
dummy, but only Victim (or Dummy) can destroy it.

-dr
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      01-27-2007
Dave Rahardja <(E-Mail Removed)> wrote:
> On Sat, 27 Jan 2007 17:00:50 GMT, "Daniel T." <(E-Mail Removed)> wrote:
> >"AndrewD" <(E-Mail Removed)> wrote:
> >
> >> Michael,
> >>
> >> Make Dummy destructor private and class Victim a friend as follows:
> >>
> >> class Dummy {
> >> public:
> >> int n;
> >> private:
> >> ~Dummy() {}
> >> friend class Victim;
> >> };

> >
> >Now Dummy can't be created by any other class than Victim. That's a
> >rather draconian restriction just to safe-guard some data from delete.

>
> How's that? The default constructor is still public. Anyone can construct
> dummy, but only Victim (or Dummy) can destroy it.


Sorry, I was thinking about auto variables, however as a practical
matter not being able to destroy what you create can be a big problem.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"return delete (new int)" compile but "return delete (new X X C++ 4 07-19-2010 05:47 PM
Storing and Exposing a Complex Object Property In Viewstate daokfella ASP .Net 1 08-08-2008 08:26 PM
how can I transfer the login information from classic asp to asp.net, without exposing the password? bill ASP .Net 3 10-10-2005 08:01 AM
Re: Exposing object model in Python? MK Python 8 07-01-2003 04:05 AM
Re: Exposing object model in Python? Graham Fawcett Python 0 06-27-2003 04:13 AM



Advertisments