-
Calling a pure virtual function
I'm working on a safety critical project using C++, so we have to think about really pathological conditions. We're using an OS (+ stuff) that says it can detect an attempt to call a pure virtual function.
How could that happen? The only objects that exist were created, and the only objects you can create are from concrete classes.
I'm sure there's a way, but I don't know what it is. Does anyone out there know how to accidentally call a pure virtual function?
Thanks,
John
-
And the answer is... when you call a virtual function within a constructor or destructor of a derived class.
You should never call a virtual function within a constructor or destructor because it might invoke the definition of the base class. If the definition in the base class is "=0", you end up with a bad day.
-
Actually, it's more complex than that. You *can* call a pure virtual function in some cases, and you're also obliged to *define* it in at least one case.
Calling a pure virtual function is possible by using typecasting or a pointer to member that pretends to point to a valid virtual function. In all cases (except a pure virtual destructor), this should lead to a runtime exception.
With respect to destructors: when you declare a pure virtual destructor you need to define it as well (notice that the pure specifier =0; doesn't prohibit a separate definition. It merely disables the instantiation of objects of that class) because the destructor of a derived class automatically invokes its base class's dtor.
Last edited by Danny; 05-24-2009 at 06:53 PM.
Danny Kalev
-
Someone gave me an example:
[/Code]
#include <iostream>
using namespace std;
class A
{
public:
A()
{
helper();
}
virtual void vfun() = 0;
private:
void helper()
{
vfun();
}
};
class B : public A
{
public:
B()
{
cout << "Constructing B..." << endl;
vfun();
}
virtual void vfun()
{
cout << "Inside B::vfun" << endl;
}
};
int main()
{
cout << "About to create instance of class B on stack..." << endl;
B b;
b.vfun();
cout << "If we get here, pure virtual isn't really pure..." << endl;
}
[/Code]
It threw a segmentation fault. First it printed "virtual method called."
Apparently the compiler put in code for the pure virtual that printed the message and raised the signal.
-
I realize that the error occurred when the constructor for B implicitly called the constructor for A (which called helper() which call A::vfun())
Is it accurate to say that when you call a virtual function from within a constructor, it is undefined whether the base class's version or the derived class's version is invoked?
-
No, it's very well defined: a constructor will not call a virtual function defined in an object whose type is more derived than that of the constructor itself. In other words, when A's ctor is running it will only call virtual function from A, never from B because at this point, B has not been constructed and there's no virtual pointer through which you can call a virtual function of B (the constructor sets the vptr's value, among other things). So what you see here is a private case of how constructors resolve calls to virtual functions.
There's one exception to this rule, namely virtual inheritance because virtual bases are constructed before non-virtual ones.
Danny Kalev
Similar Threads
-
Replies: 2
Last Post: 12-02-2006, 03:29 PM
-
Replies: 4
Last Post: 04-14-2006, 09:09 AM
-
By MyPlague in forum .NET
Replies: 2
Last Post: 03-20-2006, 05:18 PM
-
By Burt in forum VB Classic
Replies: 0
Last Post: 12-16-2002, 03:14 PM
-
By Dan in forum VB Classic
Replies: 0
Last Post: 03-17-2000, 05:14 AM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks