Avoid virtual function when calling common code in destructor

  • Permalink
  • submit to reddit
  • Email
  • Follow


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
Reply kevin.grigorenko (2) 1/12/2005 8:55:32 PM

See related articles to this posting


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
Reply 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
Reply 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
Reply 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
Reply Antoun 1/13/2005 9:50:06 PM
comp.lang.c++.moderated 10658 articles. 9 followers. Post

4 Replies
246 Views

Similar Articles

[PageSpeed] 43


  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

calling virtual destructors and virtual functions
Say I have a class A, and a class B that inherits from A. Now A (and B) has a virtual destructor and a virtual function F(); If I now make these statements A* ptrA = new B; ptrA->F(); delete ptrA then in the statement ptrA->F(), by means of the polymorph behavior, the F() of class B is called. But the F() of class B only. And in delete ptrA, both destructors of class A and B are called. Is this right? Because then the two statements behave differently. Somehow, for a moment, I was thinking that in the call ptrA->F(), both virtual functions of class A and B should be processed. *...

Calling virtual functions from destructors?
Hi I've had a problem with gcc mac osx which I think I figured out. I would like to double check with people here to see if my understanding is correct: I have a class A which class B inherit from. A has a pure virtual function virtual in f1() = 0. In B I implement this function and the compiler works out the code. However from A's destructor B can be compiled and then the runtime aborts with saying that a call to a pure virtual function is not allowed. I'm assuming that B's destructor has been called before A's destructor and thus it won't allow me to call the...

clarification
Hello class A { public: virtual void Func1() = 0; void Func1Caller() { Func1(); } ~A() { Func1Caller(); } }; class B : public A { public: virtual void Func1() { printf("this is func1\n"); } }; int main() { B t; return 0; } It seems that VC is not allowing Func1Caller() to call Func1() from the destructor. Don't know if this a C++ issue or a compiler issue. Can someone clarify and provide a workaround? -- Elias Every class is better has own constructor and deconstructor itself, even if compiler allow you do that. Class A func1 alway be called In ...

Problem with virtual functions called from a destructor
This is a simplified version of the situation (the actual situation is quite more complex, but when stripped to the bare minimum, it's like this): class BaseClass { public: virtual void cleanup(); virtual ~BaseClass() { cleanup(); } }; The cleanup() function is not only called when destroying the object but also at other times during the lifetime of the object, and it's usually called through a BaseClass pointer and sometimes implemented in a derived class. Naturally the problem is that the BaseClass destructor will not call the implementation of cleanup() in the deri...

avoiding virtual call with pointer to member function
Hi to all, a newbie question. Is it possible to avoid the virtual mechanism with pointers to members syntax the same way it's done with an explicit call ( obj.Base::Func() )? It would be useful for something I'm doing... check out the trivial program down here... Thanks in advance, Francesco #include <iostream> struct Base { virtual ~Base() {} virtual void Do() const { std::cout << "Base\n"; } }; struct Der : public Base { virtual void Do() const { std::cout << "Der\n"; } }; int main() { Der obj; obj.Base::Do(); // avoid virtual call...

Calling pure virtual functions from an abstract class constructor or destructor.
I'm trying to understand the scope of 10.4/6: struct C1 { void void bar () = 0; }; struct C2 : public C1 { C2 () : C1() {} void void bar () { } }; struct B : public C2 { B (); virtual void foo () = 0; }; B::B () : C2() { foo (); // (1) undefined from 10.4/6 bar (); // (2) undefined? } My interpretation of 10.4/6 makes both of these undefined behaviour. However, I do not see a justification for disallowing (2). Am I understanding something in the paragraph? Regards, Richard -- Richard Corden ---...

calling virtual function from within another virtual function
Hi Guys, Is Ok to invoke a virutal function from within virtual function. Specifically here is the example I tried and it seems to have worked: (what I am doing is derived class::foo() (foo is virtual)invokes base case implementation of foo(), which in turn calls bar() thats virutal too . So I am reusing some part of logic which is common to both base and derived and overriding other part which is different by using 2 virtual functions like this) #include <iostream.h> using namespace std; class C { public: virtual void foo(int foo) { cout << "in C::foo() foo="...

calling virtual function results in calling function of base class ...
Hi, after browsing FAQ and archive for a while I decided that the following is a legal question. Consider this: Class Base { public: Base() {} Base(A* a, B* b); virtual A* foo(P* p, S& s); // using myA and myB protected: A* myA; B* myB; }; class Der : public Base { public: Der(O* o) : Base(), myO(o) {} A* foo(P* p; S& s); // not using myA and myB private: O* myO; }; class Bogus { public: Bogus(Base* b) : myBase(b) {} void bar() { ... myBase->foo(p,s); ... } private: Base* myBase; }; int main(/*args*/) { ... Der der(someO); Bogus* bogus = new Bogus(d...

calling virtual function results in calling function of base class ... #2
On Andreas Lagemann <andreas.lagemann@freenet.de> wrote: > > Class Base > { > public: > Base() {} > > Base(A* a, B* b); > > virtual A* foo(P* p, S& s); // using myA and myB Make sure you have a virtual destructor, private copy constructor and private assignment operator. > Executing this results in Base::foo being called instead of Der::foo Did you make a typo or something. It will call Der::foo if your foo signature is exact the same in Der. Are you sure you use pointers when you are passing the Der object as a Base object? To make sure use pri...

virtual destructors for classes only with virtual functions?
Hi, Most of the books on C++ say something like this: "A virtual destructor should be defined if the class contains at least one virtual member function." My question is: why is it only for the case when the class contains at least one virtual member function? Shouldn't the destructor always be virtual, whenever there's a possibility that an inherited object will be destructed through a base class pointer? (This does not require, that the base class have any other virtual function!) Thanks! ps: can someone please explain me briefly, why a concrete base class cannot have a...

accessing errno in CFM code of a MACH-O. function call (Apple's sample code "Call Mach-O Framework")
Hi. I'm using Apple's sample code "Call Mach-O Framework", to access I/O Kit function calls (open(), read(), write()). I've been using the function pointer method. It's been working fine for months, and what simple error handling I've needed I've been able to handle with the return values of the function calls. Now I need to add a more elaborate error handling scheme which requires that I know the value of errno. To my suprise, errno is always zero, even after a function call returns an error. I'm guessing that the real errno is in the Mach-...

calling parent virtual function wtih out calling it
hi all, hope some one can help me. Ill try and explain what im trying to do as best i can. i have a parent class that has a vertual function, lets call it virtual int A(). That vertual function does somthing that must be done. This meens that when a child class inherits the class and creates its own vertual int A() the parent class must also be called. the prob is i can not use the base class name and then its functino name after it from with in the child class to call it. is there any way to make it so that all the verutal functions that are made are exectued. The reson its a verutal fu...

Automatic virtual destructors for classes with virtual functions
Hello! I was thinking about improvements that could be made to the C++ language in order to make it easier for beginners (and for expert users as a side-effect). Then the non-virtual destructor problem came to my mind. It's considered good practice to declare a virtual destructor if a class has at least one virtual function. Failing to do so could easily lead to undefined behavior. So, why not make the language take care of this? As a real-world example, when a programmer wants to imitate Java or C# interfaces, he/she needs to write something like this: struct PureAbstra...

virtual overloaded functions and base class function call...
Hello, First sorry for my poor English, I am French ;-) I've got a comprehension problem of what happend in one of the project i'm working on. Basically I've got a class gs_object than has got a VIRTUAL function createList(). This createList() function is overloaded in another class named ct_server that inherits gs_object. in my code, it looks something like that : class gs_object { ... virtual void createList(); ... }; class ct_server : public gs_object { ... virtual void createList(); void initInstance(); ... }; Here is the problem : in the function ct_server::initI...

same overhead in calling virtual and non virtual member function...?
Hello All, So far I have been reading that in case of a polymorphic class ( having at least one virtual function in it), the virtual function call get resolved at run time and during that the vtable pointer is made use of.. eg. class one { virtual void fun1(){ cout<<"one::fun1";} //This is a virtual function. void fun2(){ cout<<"one ::fun2";}//Not a virtual function. }; int main() { one * o = new one; o->fun1(); o->fun2(); delete o; o= NULL; return 0; } so when the virtual function gets called through the base class poitner the call actua...

virtual overloaded functions and base class function call...
Hello, First sorry for my poor English, I am French ;-) I've got a comprehension problem of what happend in one of the project i'm working on. Basically I've got a class gs_object than has got a VIRTUAL function createList(). This createList() function is overloaded in another class named ct_server that inherits gs_object. in my code, it looks something like that : class gs_object { ... virtual void createList(); ... }; class ct_server : public gs_object { ... virtual void createList(); void initInstance(); ... }; Here is the problem : in the function ct_server::initI...

non-virtual call to a virtual function using pointer to member
Hi. for example i have base class A and dirved class B: struct A { virtual void f() { std::cout << "A::f()" << std::endl; } }; struct B : public A { void f() { std::cout << "B::f()" << std::endl; } }; int main() { B b; A *a = &b; a->f(); // virtual call. calls B::f() a->A::f(); // non-virtual call. calls A::f() A::* pf; pf = &A::f(); (a->*pf)(); // virtual call. calls B::f() pf = /* ??? */; // what should i write here for desired effect(non- virtual call) (a->*pf)(); // non...

Bypass virtual function call when calling direcltly with a object/reference of that type?
Hi all, here's the situation, just for demo: struct Base { virtual void f() = 0; }; struct A: Base { virtual void f(); }; template<class T> inline T& by_ref(T& t) { return t; } struct wrappedA { A _a; void f(){ _a.f(); } }; ------------------------------- Here we have types(Base, A, wrappedA) and an inline function(by_ref) which returns reference; Base has a virtual member function 'f' which A overrides, and what f does does not matter. Now consider: A a; wrappedA ra; Base* p = &a; Followin...

calling matlab code in labview 5 using call library function
hai i have a problem........... i want to call matlab code through call library function or cal interface node and execute it in my labview 5.but as i configer the dll. file in my CLF, it shows error saying function not found in library. i want brief explanation of how to create dll.in matlab and how to call it in labview5 CLF.can anybody help me? divya shetty. :?: ...

Destructor calling order from function calls different from <Effective C++>
Hey, In the book <Effective C++>, the author provides an example to prove why we need "pass by reference". I redoed the example, and found something interesting. The codes are: ############################## #include <iostream> class Student{ public: Student(){ std::cout << "inside CTOR. this = " << this << std::endl << std::endl; } Student(const Student& rhs){ std::cout << "inside COPY CTOR. this = " << this << ", rhs = "<< &rhs << std::endl <<...

Should virtual functions be avoided?
From my perusings of the boost-devel list, it appears to me that modern C++ library writers go to great lengths to avoid the use of virtual functions. Is this assertion true, or have I formed a false impression? I've managed to factor a large chunk of common code into a base class, but need to use class process_data; class process_base { virtual ~process_data() {} virtual process_data & data() = 0; virtual process_data const & data() const = 0; public: ... }; to do so. The d...

Virtual function call
Hello, i have a strange problem, when calling virtual function, using SDL Thread library. Here is situation: CThread::CThread { SDL_CreateThread(RunProc,this); } virtual bool CThread::IsRunning() { return false; } int SDLCALL CThread::RunProc(void *pParam) { /*delay 100ms*/ CThread *pt=(CThread *)pParam; while (pt->IsRunning()) { pt->DoRun(); } } then I make: class CMyThread : public CThread { virtual bool IsRunning() { return true; } }; After new CMyThread() I expect to function IsRunning to return true, but it returns false as in ...

Call to a function, doesn't end up at the function, but at a arbitrary looking place in the code.
Hey, I've got a function, func() declared in helper.h, and defined in helper.cpp If I call this function from mycode.cpp (which includes helper.h), and I use the debugger to see what happens, it doesn't jump to the func() function. Instead it jumps to an arbitrary looking place in the code (altough in the correct file: helper.cpp). I haven't got a clue how I could possibly find out what's the problem, I've tried renaming the function, changing the types of its parameters, putting it in a namespace, all to no avail. If I comment out the code that is being ...

Call to a function, doesn't end up at the function, but at a arbitrary looking place in the code. #2
Hey, I've got a function, func() declared in helper.h, and defined in helper.cpp If I call this function from mycode.cpp (which includes helper.h), and I use the debugger to see what happens, it doesn't jump to the func() function. Instead it jumps to an arbitrary looking place in the code (altough in the correct file: helper.cpp). I haven't got a clue how I could possibly find out what's the problem, I've tried renaming the function, changing the types of its parameters, putting it in a namespace, all to no avail. If I comment out the code that is being ...