[SOLVED}stack vs. heap objects: how to destruct only heap ones?
-
Suppose we have a class:
class container
{
public:
container(sometype *itp)
{
item = itp;
}
~container();
private:
sometype *item;
};It's possible to use the class object in these ways:
void function()
{
sometype item;
sometype *pitem;container ct1(&item);
pitem = new sometype;
container ct2(pitem);
}I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?
-
Suppose we have a class:
class container
{
public:
container(sometype *itp)
{
item = itp;
}
~container();
private:
sometype *item;
};It's possible to use the class object in these ways:
void function()
{
sometype item;
sometype *pitem;container ct1(&item);
pitem = new sometype;
container ct2(pitem);
}I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?
There is no way to tell just by the variable itself, but you could provide a flag to the constructor to indicate the difference:
class container
{
public:
container(sometype *itp, bool HeapFlag)
{
item = itp;
Flag = HeapFlag;
}
~container();
{
if (Flag)
delete item;
}
private:
sometype *item;
bool Flag;
};The difficult we do right away... ...the impossible takes slightly longer.
-
Suppose we have a class:
class container
{
public:
container(sometype *itp)
{
item = itp;
}
~container();
private:
sometype *item;
};It's possible to use the class object in these ways:
void function()
{
sometype item;
sometype *pitem;container ct1(&item);
pitem = new sometype;
container ct2(pitem);
}I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?
The best way to solve this is to build it into the constructor. Use a boolean with the constructor to specify whether the class should take ownership of the
sometype
and be responsible for destroying it.class container
{
public:
container(sometype *itp, bool takeOwnership)
{
item = itp;
owner = takeOwnership
}
~container();
private:
sometype *item;
bool owner;
};void function()
{
sometype item;
sometype *pitem;container ct1(&item, false);
pitem = new sometype;
container ct2(pitem, true);
} -
There is no way to tell just by the variable itself, but you could provide a flag to the constructor to indicate the difference:
class container
{
public:
container(sometype *itp, bool HeapFlag)
{
item = itp;
Flag = HeapFlag;
}
~container();
{
if (Flag)
delete item;
}
private:
sometype *item;
bool Flag;
};The difficult we do right away... ...the impossible takes slightly longer.
I think I've just found pretty good solution which, however, may not work well in multithreaded environment. Let's add a static variable
bool heapcreated
, a flagcreatedflag
and overload operatornew
. That would look like this:class sometype
{
protected:
static bool heapcreated;
bool createdflag;
public:
sometype()
{
createdflag = heapcreated;
heapcreated = false;
}
bool IsHeapCreated()
{
return createdflag;
}
void *operator new(size_t n)
{
sometype *stp=::new sometype;heapcreated = true; return stp; }
class container
{
public:
container(sometype *itp)
{
item = itp;
}
~container();
{
if (item->IsHeapCreated())
delete item;
}
private:
sometype *item;
};The new destructor of
container
would behave different depending on mode ofsometype
creation. I've searched this solution to be used when you build a library and you do not want a caller to have to do an overhead work adding a flag parameter. If you had to make many calls tocontainer
constructor with pointers tosometype
it would be slightly difficult to save somewhere the pointers and then delete them. Also, you should be able to pass a pointer to stack variable which must not be deleted explicitly. It's a bit tricky but my simple test works. -
I think I've just found pretty good solution which, however, may not work well in multithreaded environment. Let's add a static variable
bool heapcreated
, a flagcreatedflag
and overload operatornew
. That would look like this:class sometype
{
protected:
static bool heapcreated;
bool createdflag;
public:
sometype()
{
createdflag = heapcreated;
heapcreated = false;
}
bool IsHeapCreated()
{
return createdflag;
}
void *operator new(size_t n)
{
sometype *stp=::new sometype;heapcreated = true; return stp; }
class container
{
public:
container(sometype *itp)
{
item = itp;
}
~container();
{
if (item->IsHeapCreated())
delete item;
}
private:
sometype *item;
};The new destructor of
container
would behave different depending on mode ofsometype
creation. I've searched this solution to be used when you build a library and you do not want a caller to have to do an overhead work adding a flag parameter. If you had to make many calls tocontainer
constructor with pointers tosometype
it would be slightly difficult to save somewhere the pointers and then delete them. Also, you should be able to pass a pointer to stack variable which must not be deleted explicitly. It's a bit tricky but my simple test works.Good on you! That's a clever solution. :)
The difficult we do right away... ...the impossible takes slightly longer.