473,394 Members | 1,703 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

operator delete problem.

ct
Hi,

Here is my problem: I need to be able to call a virtual method when an
object is deleted.

class A
{
public:
virtual ~A();
void virtual DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void virtual DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{

}

void B::DestroyRespond()
{
printf("destruction of B\n");
A::DestroyRespond();

}
int main(int argc, char* argv[])
{
B *b = new B();

delete b;
}
obviously this will never work, the virtual method of object B will
never get called on the destruction of B.

Is there a way ""overloading the operator delete"" for example that will
solve my problem.

here is one of the limitation cannot call A::operator delete b; i need
this to be transparent as part of a framework. I also know that with a
smart_pointer this could be solve but i also neet the contruction of B
to be standart.

the framework needs to be standart

B *b = new B();
delete b;
the ouput will need to be

destruction of B
destruction of A
thanks.
Aug 25 '05 #1
10 1481
This works (although little different than yours) :

#include <iostream>
using namespace std;

class A {
public:
virtual ~A() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~A" << endl;
}
};

class B : public A {
public:
virtual ~B() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~B" << endl;
}
};

int main() {
B* b = new B;
A* a = new B;
delete b;
delete a;
return 0;
}

you have to call DestroyRespond in ~B.
see, objects are constructed starting from the top most base constructor,
and destructed starting with the bottom most destructor. so, by the time you
get to the ~A, the B part of the object is long gone, and so is the type
info, therefore virtual A::DestroyRespond will be called in ~A, simply
because B doesn't exist anymore.

hope that helps

"ct" <ro*******@yahoo.com> wrote in message
news:MP************************@news.videotron.ca. ..
Hi,

Here is my problem: I need to be able to call a virtual method when an
object is deleted.

class A
{
public:
virtual ~A();
void virtual DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void virtual DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{

}

void B::DestroyRespond()
{
printf("destruction of B\n");
A::DestroyRespond();

}
int main(int argc, char* argv[])
{
B *b = new B();

delete b;
}
obviously this will never work, the virtual method of object B will
never get called on the destruction of B.

Is there a way ""overloading the operator delete"" for example that will
solve my problem.

here is one of the limitation cannot call A::operator delete b; i need
this to be transparent as part of a framework. I also know that with a
smart_pointer this could be solve but i also neet the contruction of B
to be standart.

the framework needs to be standart

B *b = new B();
delete b;
the ouput will need to be

destruction of B
destruction of A
thanks.

Aug 25 '05 #2
* ct:
[description of "virtual clean-up" problem]


I'm 75% sure that this is really just confusion over the way destructors
work, in which case a solution would be

struct A
{
virtual ~A() { std::cout << "A destroyed.\n"; }
};

struct B: A
{
virtual ~B() { std::cout << "B destroyed.\n"; }
};

which for destruction of a B object outputs both messages, B's first.

However, there is a 25% chance, or thereabouts, that you're referring to the
destruction analogoue of dynamic binding during construction, FAQ item 23.4.

And if so the solutions are essentially the same.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Aug 25 '05 #3
ct wrote:

Hi,

Here is my problem: I need to be able to call a virtual method when an
object is deleted.
That won't work.
When the base class destructor runs, the derived class portion of that
object has been destroyed already. The object is no longer from derived
class type, but is a base class object.
B *b = new B();
delete b;

the ouput will need to be

destruction of B
destruction of A


class A
{
public:
virtual ~A();
void DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{
DestroyRespond();
}

void B::DestroyRespond()
{
printf("destruction of B\n");
}

The DestroyRespond functions are called exactly in the
order you want them.

--
Karl Heinz Buchegger
kb******@gascad.at
Aug 25 '05 #4
ct
I understand that calling DestroyRespond on B would solve my problem,
but i do not want to this, to hard to maintain and very confusing for
junior programmer that are new to the api.

Charles.


In article <de**********@news.onet.pl>, mv*******@poczta.onet.pl says...
This works (although little different than yours) :

#include <iostream>
using namespace std;

class A {
public:
virtual ~A() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~A" << endl;
}
};

class B : public A {
public:
virtual ~B() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~B" << endl;
}
};

int main() {
B* b = new B;
A* a = new B;
delete b;
delete a;
return 0;
}

you have to call DestroyRespond in ~B.
see, objects are constructed starting from the top most base constructor,
and destructed starting with the bottom most destructor. so, by the time you
get to the ~A, the B part of the object is long gone, and so is the type
info, therefore virtual A::DestroyRespond will be called in ~A, simply
because B doesn't exist anymore.

hope that helps

"ct" <ro*******@yahoo.com> wrote in message
news:MP************************@news.videotron.ca. ..
Hi,

Aug 25 '05 #5
ct
In article <43***************@gascad.at>, kb******@gascad.at says...
ct wrote:

Hi,

Here is my problem: I need to be able to call a virtual method when an
object is deleted.


That won't work.
When the base class destructor runs, the derived class portion of that
object has been destroyed already. The object is no longer from derived
class type, but is a base class object.

I know, this is exacly what i'm asking , is there a way to make this
architechture workable.
B *b = new B();
delete b;

the ouput will need to be

destruction of B
destruction of A


class A
{
public:
virtual ~A();
void DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{
DestroyRespond();
}

void B::DestroyRespond()

Aug 25 '05 #6
ct, I just tried overriding the operator delete for your class B

void B::operator delete(void* deadObject)
{
// deallocate B part of deadObject
// deallocate A part of deadObject
}

However, void BMary::operator delete(void* deadObject) is a static
member function so you can't explicitly invoke the virtual destructors
of A and B. You can use the global operator delete (i.e. ::delete
deadObject) but I don't think this what you want.
This means that you hypothetically would have to first
deallocate the B part of the deadObject pointer, followed by the A part
of the deadObject pointer. This task is highly problematic because the
layout of objects in memory is highly compiler dependent so it would be
hard to extract the B part and A part of the deadObject pointer.

Aug 25 '05 #7

ct wrote:
Hi,

Here is my problem: I need to be able to call a virtual method when an
object is deleted.

class A
{
public:
virtual ~A();
void virtual DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void virtual DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{

}

void B::DestroyRespond()
{
printf("destruction of B\n");
A::DestroyRespond();

}
int main(int argc, char* argv[])
{
B *b = new B();

delete b;
}
obviously this will never work, the virtual method of object B will
never get called on the destruction of B.

Is there a way ""overloading the operator delete"" for example that will
solve my problem.

here is one of the limitation cannot call A::operator delete b; i need
this to be transparent as part of a framework. I also know that with a
smart_pointer this could be solve but i also neet the contruction of B
to be standart.

the framework needs to be standart

B *b = new B();
delete b;
the ouput will need to be

destruction of B
destruction of A
thanks.


Why not just move whatever code is in A::DestroyRespond() into A::~A()
and move whatever code is in B::DestroyRespond() into B::~B()?

These two routines are presumably only ever called from one point in
the code, so why make two class methods distinct from the classes'
destructors?

Greg

Aug 25 '05 #8
Do not toppost!
reformatted

"ct" <ro*******@yahoo.com> wrote in message
news:MP************************@news.videotron.ca. ..
In article <de**********@news.onet.pl>, mv*******@poczta.onet.pl says...
This works (although little different than yours) :

#include <iostream>
using namespace std;

class A {
public:
virtual ~A() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~A" << endl;
}
};

class B : public A {
public:
virtual ~B() {
DestroyRespond();
}

virtual void DestroyRespond() {
cout << "~B" << endl;
}
};

int main() {
B* b = new B;
A* a = new B;
delete b;
delete a;
return 0;
}

you have to call DestroyRespond in ~B.
see, objects are constructed starting from the top most base constructor,
and destructed starting with the bottom most destructor. so, by the time
you
get to the ~A, the B part of the object is long gone, and so is the type
info, therefore virtual A::DestroyRespond will be called in ~A, simply
because B doesn't exist anymore.

hope that helps

"ct" <ro*******@yahoo.com> wrote in message
news:MP************************@news.videotron.ca. ..
> Hi,
>
I understand that calling DestroyRespond on B would solve my problem,
but i do not want to this, to hard to maintain and very confusing for
junior programmer that are new to the api.

Charles.

Let's assume that what you want (call virtual function in destructor) is
possible. Still the junior programmer would have to provide the virtual
DestroyResponse method in the derived class. Isn't this as hard to maintain
as the solution above? Why not implement the actions of DestroyResponse
directly in the body of destructor? A good example of this approach is the
asignment operator and copy constructor. In 99% of the cases they both do
the same thing. How about changing the name of DestroyResponse into Cleanup
or Clear?

/dan
Aug 26 '05 #9
Dan Cernat wrote:

I understand that calling DestroyRespond on B would solve my problem,
but i do not want to this, to hard to maintain and very confusing for
junior programmer that are new to the api.

Charles.


Let's assume that what you want (call virtual function in destructor) is
possible. Still the junior programmer would have to provide the virtual
DestroyResponse method in the derived class. Isn't this as hard to maintain
as the solution above? Why not implement the actions of DestroyResponse
directly in the body of destructor? A good example of this approach is the
asignment operator and copy constructor. In 99% of the cases they both do
the same thing. How about changing the name of DestroyResponse into Cleanup
or Clear?


Agreed.
Besides that. Isn't one of the main abilities, that a junior programmer
has to learn, the ability of discipline? That includes: doing things the
way they are supposed to be done.

Moving that code into the destructor isn't really rocket sience and I wouldn't
call it: 'to hard to maintain and very confusing'. It is just normal C++
practice. If a junior programmer cannot be tought this, maybe that junior is
the wrong person for programming C++.

Don't get me wrong. I am all with the OP, to make things as easy as possible.
But there are always basic things that every involved person must be able
to do when doing X. Working with destructors in C++ is such a thing.

--
Karl Heinz Buchegger
kb******@gascad.at
Aug 26 '05 #10
ct wrote:

(snip)
class A
{
public:
virtual ~A();
void virtual DestroyRespond();
};

class B : public A
{
public:
virtual ~B();
void virtual DestroyRespond();
};

A::~A()
{
DestroyRespond();
}

void A::DestroyRespond()
{
printf("destruction of A\n");
}

B::~B()
{

}

void B::DestroyRespond()
{
printf("destruction of B\n");
A::DestroyRespond();

}
int main(int argc, char* argv[])
{
B *b = new B();

delete b;
}


Such a design is also potentially harmful. For example,

int main(int argc, char* argv[])
{
A *a = new B();
a->DestroyRespond(); // Cleanup Done
// or so the programmer thought
}

or

int main(int argc, char* argv[])
{
A *a = new B();
a->DestroyRespond();
delete a; // DestroyRespond() Called again. May not be good news.
}

Aug 26 '05 #11

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

Similar topics

2
by: skscpp | last post by:
I have a question about multiple inheritance, operator new/delete and ambiguity. Here is some code that I wrote to analyze this problem. // test.h ========================== #include <new>...
1
by: Senthilvel Samatharman | last post by:
I am just curious about the case 3 in the follwouing program. I understand that case 1 is the right way to overload, while Case 2 is erroneous. But i do think that the implementation of operator...
11
by: Jonan | last post by:
Hello, For several reasons I want to replace the built-in memory management with some custom built. The mem management itlsef is not subject to my question - it's ok to the point that I have...
5
by: kUfa.scoopex | last post by:
Hi there! I have a small problem, and i really dont see any convenient way to fix it. Basically, i'd like to overload global new operators, into something like this: void *operator new(...
13
by: Amy | last post by:
Hello, We are developing C++ appplications for PDAs where memory is limited, so we want to do memory management by ourselves --- pre-allocated a big chunk and overwrite new and delete to call...
13
by: Alex Vinokur | last post by:
Is the any difference between ------ 1 ------ Foo* p = operator new (n * sizeof (Foo)); // Stuff delete p; --------------- and
3
by: md | last post by:
Hi, the following code is working for static objects. ie the statement IntArray x(20); my problem is i want to use this overloading operator for dynamically created objects...
6
by: Lighter | last post by:
Big Problem! How to overload operator delete? According to C++ standard, "A deallocation function can have more than one parameter."(see 3.7.3.2); however, I don't know how to use an overloaded...
9
by: itdevries | last post by:
Hi, I've ran into some trouble with an overloaded + operator, maybe someone can give me some hints what to look out for. I've got my own custom vector class, as a part of that I've overloaded...
3
by: C++Liliput | last post by:
Hi, I was looking at the implementation of operator new and operator new in gcc source code and found that the implementation is exactly the same. The only difference is that the size_t argument...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.