Avoid virtual function when calling common code in destructor

Hello,

I have a class with a logical disconnect() function. This disconnect
function may be called manually and will be called in the destructor.
However, I'm not quite sure how to build this function.  I want the
disconnect() function to be virtual, but calling a virtual function
from a destructor is faux pas, correct?  Is it okay in this situation,
or otherwise, how can I do this?

Thank you,
Kevin


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
1/12/2005 8:55:32 PM
comp.lang.c++.moderated 10706 articles. 11 followers. allnor (8507) is leader. Post Follow

4 Replies
287 Views

Similar Articles

[PageSpeed] 57
Kevin Grigorenko wrote:
> Hello,
>
> I have a class with a logical disconnect() function. This disconnect
> function may be called manually and will be called in the destructor.
> However, I'm not quite sure how to build this function.  I want the
> disconnect() function to be virtual, but calling a virtual function
> from a destructor is faux pas, correct?  Is it okay in this situation,
> or otherwise, how can I do this?

There's nothing wrong with calling a virtual function in a destructor,
however, the function will resolve as if the type of the object is
of the type of the destructor.

The thing you can't do is make a virtual call to a PURE VIRTUAL
function in a destructor.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Ron
1/13/2005 12:05:57 PM
Calling a virtual function from a destructor calls the function in the
current object. You have to write your disconnect() so that it behaves
well when it is called during destruction.

struct A {
virtual void disconnect() {} //#1
virtual ~A() { disconnect(); } //Calls #1 while destruction
};

struct B : public A {
virtual void disconnect() {} //#2
virtual ~B() { disconnect(); } //Calls #2 while destruction
};


--lsu


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
L
1/13/2005 4:38:19 PM
On 12 Jan 2005 15:55:32 -0500, Kevin Grigorenko  
<kevin.grigorenko@gmail.com> wrote:

> I have a class with a logical disconnect() function. This disconnect
> function may be called manually and will be called in the destructor.
> However, I'm not quite sure how to build this function.  I want the
> disconnect() function to be virtual, but calling a virtual function
> from a destructor is faux pas, correct?  Is it okay in this situation,
> or otherwise, how can I do this?

First, you might consider to get rid of disconnect function, placing all  
cleanup in destructors. This could be the best solution with regards to  
implementation effort.

Second, the context implies that you use interface based design. If this  
is so, you may want to employ proxy design pattern or handle-envelope (aka  
pimpl) idiom, that is, you wrap all your objects with a proxy object that  
calls disconnect function from its destructor.

Example:

     struct resource
     {
         virtual void do_some() = 0;
         virtual void disconnect() = 0;
         virtual ~resource() {}
     };

     struct resource_proxy
     {
         typedef std::auto_ptr<resource> wrapped_ptr;
         wrapped_ptr const w_; // const here makes resource_decorator  
noncopyable

         // forwarding functions
         void do_some() { w_->do_some(); }
         void disconnect() { w_->disconnect(); }

         resource_proxy(wrapped_ptr w) : w_(w) {}
         ~resource_proxy() { this->disconnect(); }
     };

Client functions only deal with resource_proxy, which is initialized with  
some concrete resource object from your resource hierarchy.

-- 
Maxim Yegorushkin

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Maxim
1/13/2005 8:03:03 PM
Ron Natalie wrote:
> Kevin Grigorenko wrote:
>>I have a class with a logical disconnect() function. This disconnect
>>function may be called manually and will be called in the destructor.
>>However, I'm not quite sure how to build this function.  I want the
>>disconnect() function to be virtual, but calling a virtual function
>>from a destructor is faux pas, correct?  Is it okay in this situation,
>>or otherwise, how can I do this?
> 
> There's nothing wrong with calling a virtual function in a destructor,
> however, the function will resolve as if the type of the object is
> of the type of the destructor.

It's debatable whether calling a virtual function is 'correct' in
a destructor; for example, when you consider the OP's problem.

> The thing you can't do is make a virtual call to a PURE VIRTUAL
> function in a destructor.

You shouldn't call a pure virtual anywhere :)

Back to the OP's problem: when cleanup activity is defined/refined
in subclasses, you cannot depend on it happening through the parent
destructor, since the destructor's type context never reaches into
the subtypes.

The behavior you want requires that certain points of behavior retain
their dyanmism beyond the start of the destruction phase, or that their
final specialization happens in the same class where you call them
in the destructor.

You can do that by messing around with the type system, and placing
instantiation barriers at various places, so that a destructor call
to disconnect() always hits the right place.  This is not simple,
nor good looking; you would have to make sure that disconnect()
[and similar points of specialization] do not get refined/redefined
in the subclasses (otherwise, we're back where we started).

Or, you can partition your classes, so that the connection object
is not embedded in the class under focus, and you can disconnect()
it through the appropriate mechanism before you destroy it; e.g.:
something like this:

     class MyClass {
        connection_type *cnxn;
     public:
        virtual ~MyClass() {
            cnxn->disconnect();
            delete cnxn;
            /// more destruction ...
        }
        /// etc ....
     };

-- 
A. Kanawati
NO.antounk.SPAM@comcast.net

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Antoun
1/13/2005 9:50:06 PM
Reply:
Similar Artilces:

US-TX-Austin: SW Applications Eng., C programming,code development,GUI (45349332410)
US-TX-Austin: SW Applications Eng., C programming,code development,GUI (45349332410) ==================================================================================== Position: SW Applications Eng. Reference: ZYD00018 Location: Austin TX Duration: Skills: 5+ years of C programming experience. 3+ years of low-level code development Ability to debug software and hardware issues. GUI development experience. Experience with hardware design is a plus. Scope: Work with design team to capture applica...

Function to get only the different values of an array.
Hello, I would like to know if there is a function that returns me only the different values of an array. For example: Imagine we have the following array: a = (1 2 3 2 3 4 6 3 4) I want to know if MatLab has a function that returns me the following array: result = (1 2 3 4 6) The function is like the "SELECT DISTINCT" command of SQL. Thanks. Diego Gomes: <SNIP a matter of english... > I would like to know if there is a function that returns me only the different values of an array... a hint: help unique; us I tried the MatLab help but I couldn't find. Do ...

[News] Even Eli Lilly Starts Sharing Some Source Code
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Lilly’s Science Grid Goes Open Source ,----[ Quote ] | In an unusual move for big pharma, Eli Lilly last month made its Discovery IT | platform – known internally as the Lilly Science Grid (LSG) – open source. | The initiative could spark new interest within the biopharma community for | sharing pre-competitive content and software. `---- http://www.bio-itworld.com/BioIT_Article.aspx?id=75790 When patent-loving pharmaceuticals embrace Free software, then it's a huge development. Related: Open Source Pharmaceuticals - New Business M...

avoiding CTRL-ALT-DEL by mistake
[ please answer in and set followup to "comp.os.linux.setup" ] Well ... I've been using Windows for a long time before I switched to Linux. I'm very used to type CTRL-ALT-DEL everytime I'm leaving my computer or arriving to it. It's hapenned _twice_ (in the last six months or so) for my Linux box. I want to be able to reboot my machine with CTRL-ALT-DEL, but I don't want to do it by mistake. So, I noticed /etc/inittab has these lines # What to do when CTRL-ALT-DEL is pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now and thought I'd change ...

avoid line overlapping
Hi, I would like to visualize on which CPU specific tasks run at any given point in time in a multiprocessor system. The generated data is very simple, it just states the time in seconds and the CPU on which the task runs. If I use benchmarks with more tasks than CPUs, some points and lines of my plot do necessarily overlap each other as the CPU values are always discrete and sometimes it is rather hard to distinguish them from one another. Is there a common way to plot those lines in such a way that lines on the same y-axis value do not overlap but are drawn vertically arra...

Call for Papers (extended): IAENG International Workshop on Data Mining and Applications (in IMECS 2006)
CFP From: IAENG: International Association of Engineers (http://www.iaeng.org) Engineering Letters (http://www.engineeringletters.com) IAENG International Workshop on Data Mining and Applications 2006 (Part of The International MultiConference of Engineers and Computer Scientists IMECS 2006) IMECS 2006: 20-22 June, 2006, Hong Kong http://www.iaeng.org/IMECS2006/IWDMA2006.html The IWDMA'06 workshop is held as part of the International MultiConference of Engineers and Computer Scientists 2006. The IMECS 2006 is organized by the International Association of Engineers (IAE...

reservastrancoso@gmail.com Pousadas em Trancoso, reservas, agencia virtual, turismo Bahia
reservastrancoso@gmail.com reservastrancoso @ gmail.com (reservastrancoso@gmail.com) Pousadas em Trancoso, agencia virtual em Tancoso - Bahia. Fa�a ja sua reserva nas pousadas mais badaladas da cidade. Contato reservastrancoso @ gmail.com reservastrancoso@gmail.com (reservastrancoso@gmail.com) AxMZcLIy>x.RsSD$xTiTIpBdq ...

How to avoid repeatedly sending the same messages
In Netscape 7, how can I avoid automatic repeated sending the same messages to newsgroups? Even though I only press the Send button once, my messages to newsgroups lately tend to be sent three or more times in quick succession. I'm using Netscape 7 and OS 10.4.11. Robert "Robert Montgomery" <info-block@stargate_tech.net> wrote in message news:Xqgdj.23124$wy2.14357@edtnps90... > In Netscape 7, how can I avoid automatic repeated sending the same > messages to newsgroups? > > Even though I only press the Send button once, my messages to newsgroups > la...

VC++ Button Applications and Functions
Hi guys i am new to VC++ applications and their workings.I wnat to know how to call a file by simply clicking on the button. ...

coding the control card
hi , can anyone tell me how to code the load control cards in order to extract comma seperated data from a PS file and insert it into a table ...

Setting a constructor's prototype property to a primative, array or function.
Hi, What happens if you do this? function Person() {} Person.prototype = 7; var ted = new Person(); Also what happens if you set Person.prototype to an array or function? Thank you, Peter Peter Michaux wrote: > What happens if you do this? > > function Person() {} > Person.prototype = 7; > var ted = new Person(); See ECMA 262, 3rd Ed. Section 13.2.2 If the - prototype - property of a function that is used as a constructor is not an object (of the ECMAScript Object type) then the original value of - Object.prototype - is used to set the [[Prototype]] if the ...

Get accessor can't return by reference in const function
Hi again. I have this problem where I can't return a reference if my function is const. I have no idea why, the function works fine if I remove the "const" keyword, but I'm trying to use const-correctness by using const everywhere I can. It's a simple "Get" accessor method, I stripped the program down to the absolute bare minimum save for the single class and accessor method, but I still have the same error so I'm sure it's not elsewhere in my code. * Numero.h * #include <vector> class Numero { public: std::vector<int>& ...

memory management question (how to avoid excessive page-in, special case)
Hi, my application uses a big (~256M) static char[] as a buffer. Previously I had allocated this region via malloc but because of fragmented virtual memory the malloc call sometimes failed and so I moved to a static array (With the benefit that some dlls get mapped in a much more compact way. Now the problem: my app creates another process which also uses big amounts of memory and also does heavy I/O (DVD burning, image conversions) which causes some parts of the main app to become paged out. After the "another precess" has done its work I would like so somehow clea...

continuous to discrete s- function transfer
In continuous s-function, mdlDerivatives(t,x,u) function is as below. But how to transfer it to mdlUpdate(t,x,u) function? %%%%%%%%%%%%%%%%%%%%%%%%%%%% function sys=mdlDerivatives(t,x,u) Tx=u(1); Ty=u(2); dx(1)=x(3); dx(2)=x(4); dx(3)=Mb_p/(Mb_p+Jb_p/Rb_p^2)*(x(1)*x(7)^2+x(2)*x(7)*x(8)-g*sin(x(5))); dx(4)=Mb_p/(Mb_p+Jb_p/Rb_p^2)*(x(2)*x(8)^2+x(1)*x(7)*x(8)-g*sin(x(6))); dx(5)=x(7); dx(6)=x(8); Cx=Jp+Jb_p+Mb_p*x(1)^2; Cy=Jp+Jb_p+Mb_p*x(2)^2; Bx=Mb_p*(2*x(1)*x(3)*x(7)+x(3)*x(2)*x(8)+x(1)*x(4)*x(8)+g*x(1)*cos(x(5))); By=Mb_p*(2*x(2)*x(4)*x(8)+x(3)*x(2)*x(7)+x(1)*x(4)*x(7)+g*x...

Call for contributions to SIGAda 2008, Portland Oct. 26-30
------------------------------------------------------------------------ Practitioners - See below regarding Experience Reports ------------------------------------------------------------------------ SIGAda 2008 =========== Call for Technical Contributions - SIGAda 2008 ACM SIGAda Annual International Conference Submission Due Date: May 12, 2008 Toward Safe, Secure, Reliable Software October 26-30, 2008 Universi...

How to avoid zombies?
Hi! I have inherited a server application which was moved to Linux a couple of weeks ago. Now we see a lot of defunct processes in the process list. Essentially we spawn a new thread for each client. communicate "talks" a while with it and closes the connection afterwards. As it seems, the spawned processes end up as zombies. Can I avoid this behavior easily? Or is ignoring it the best approach? Here is some code to illustrate our approach: (I simplified it slightly, removed some error checking) while (($paddr = accept(CLIENT, SERVER)) || !$time_to_die) { if (...

Code signed Freewrapped executable fails to launch
Hello, I am trying to code sign my executable (exe) app created from wrapping tcl with Freewrap.exe. After signing, program fails to launch. From DOS command the message "Unable to initialize TCL". Anyone else experience this issue? Any work around? Thanks On Tuesday, 13 August 2013 12:45:29 UTC+5:30, Jake Cutteer wrote: > Hello, > > > > I am trying to code sign my executable (exe) app created from wrapping tcl with Freewrap.exe. > > After signing, program fails to launch. From DOS command the message "Unable to initialize TCL&quo...

freebsd and virtual pc 2004
Hi, Has anyone set up X on FreeBSD 4.10 under Microsoft Virtual PC 2004 (or similar virtual machine)? If so, I'd appreciate tips on how to configure the best resolution for the windowed OS - my intention otherwise would be to just use the --configure line on the X server to generate a default config but how to proceed from there is the trick... thanks, joel -- my opinions in this email are not endorsed by the University of Qld this message may not be onforwarded without my expressed permission Joel Hatton wrote: > Has anyone set up X on FreeBSD 4.10 under Microso...

FAQ 4.4 Does Perl have a round() function? What about ceil() and floor()? Trig functions? #13
This is an excerpt from the latest version perlfaq4.pod, which comes with the standard Perl distribution. These postings aim to reduce the number of repeated questions as well as allow the community to review and update the answers. The latest version of the complete perlfaq is at http://faq.perl.org . -------------------------------------------------------------------- 4.4: Does Perl have a round() function? What about ceil() and floor()? Trig functions? Remember that "int()" merely truncates toward 0. For rounding to a certain number of digits, "sprintf()" o...

process virtual address space
How does the virtual address space of a process get allocated? pmap -xa 304 [several lines deleted] 304: sh Address Kbytes RSS Anon Locked Mode Mapped File 00010000 88 88 - - r-x-- sh 00036000 8 8 - - rwx-- sh what is the logic behind the above segment mapping begining at 00036000? If I try to add up (on the assumption that VA space is contigious for similar segments), it doesn't add up. I have an idea that dynamic linker is involved in the set up VA space. Some futher explanation or any pointers to how to understand that me...

Call OLE #2
Hi all, How to call OLE in MATLAB ? For example ' the drag and drop OLE' . How to call it in matlab program? Regards Anshu ...

Filters : a library implementing image filters and image processing functions
Dear members, I would like to inform you that we have released our last version of the open source library "Filters". We will appreciate your feedback. link : http://filters.sourceforge.net/ Regards In short, no source code = crap. Come back when you've got something real to download, a few demos and some API's don't equate to much these days... edurand wrote: > Dear members, > I would like to inform you that we have released our last version of > the open source library "Filters". We will appreciate your feedback. > link : http://filters.so...

UML, Code Generation & Reengineering for Ada
WinA&D 4.0 Software Engineering Made Easy for Windows Placitas, NM ? Excel Software started shipping WinA&D 4.0, an engineering tool for requirements management, software modeling, code generation, reengineering and flexible report generation. Thousands of software developers in consulting, industrial and defense companies including GM, Raytheon, Northrop-Grumman, Lockheed Martin, IBM, EDS and CSC use WinA&D for structured analysis & design, multi-task design, UML based object-oriented design and database design. WinA&D 4.0 packs major enhancements for modeling, reengine...

using for loop in a function with tcptrace
Hi Guys, I have a function (BELOW) which uses tcptrace and ngrep command tools. I hope you guys are familiar with these tools. src_port='/var/port.list' trace_file='tcpdump.trace' sample_period='mar-2005' function port_trace { mkdir PortTraces; # Makes a directory echo "######CREATE PORTS packet traces######"; #remove unwanted formatting from the tcptrace output and put the values in a file refrenced by src_ports $tcptrace $trace_file | sed 's/:/ /g' | awk '{ print $6 }' | tail +8 \ > $src_port; for ports in $(cat $src_port) # for the...

Xen on a laptop. Virtualization as an alternative to dual boot or emulators.
Has anybody done a Xen installation on a Laptop? I was thinking if WinXP+Fedora on top of Xen might be a viable option. Or not? Currently my Laptop runs WinXP because of all the "Win-only" work related software I must use. (Yes I know, it sucks! ) But I am really dying to have a Linux installation too. I tried Win emulators on Fedora before but they don't work so well as a native installation of WinXP. I could have a dual boot but its a pain to reboot each time. With vitualization I can dynamically switch between the two, right? I do have a 2 year old Inten Duo 1.6 Ghz...