[SOLVED] C++: Does it make sense to *define* the pure virtual functions in the *abstract base* class itself?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
There are two possible purposes for providing member function bodies in a parent class; the first is to provide a default behaviour, and the second is to provide shared functionality to derived classes.
Since an abstract class does not need default behaviour, then only the second of these applies in this case. In other words, the pure virtual member body is functionality that may be useful to derived classes.
By "shared functionality" do you mean that derived class can
call it if and when it likes?
If yes, then doesn't it make more sense to simply remove the
"abstract" feature and let the class breath (allow to create
objects)?
Go back to the classic example of defining shapes: triangle, circle, polygon, rectangle, and a square (a special rectangle). For each of these shapes, you could compute the perimeter of the shape or even the area occupied by the shape. The means for computing these attributes will vary between the various shapes, thus it would not be practical for a base-class to define a "default" implementation of the functions needed to compute these values.
Thus, one can view "shape" as an abstract entity which defines the methods for perimeter() and area(). The aforementioned shapes would derive from this base class, and implement their respective methods for computing perimeter() and area(). So for example:
C++: Does it make any sense to define the *pure* virtual functions in the base class itself?
Yes, it does. See COM interface declarations for windows platform, "interface" pattern, "command" pattern and "visitor" pattern. It is an incredibly useful language feature, that simplifies creation of plugins, allows you to replace callbacks with classes, and so on. Also your base abstract class may implement partial algorithm that requires data provided by children of that class.
Code:
#include <iostream>
using namespace std;
class speciesFamily
{
public:
virtual void numberOfLegs () = 0;
};
Thus, one can view "shape" as an abstract entity which defines the methods for perimeter() and area(). The aforementioned shapes would derive from this base class, and implement their respective methods for computing perimeter() and area(). So for example:
Actually my question was about *defining* the pure virtual
function in the *abstract base* class. I don't see anything
like that in your example.
Actually my question was about *defining* the pure virtual
function in the *abstract base* class. I don't see anything
like that in your example.
I misread your question. You might want to rename question to something like that "Function body for pure virtual methods?"
SO has similar question - with answers. Also there are those examples.
As far as I can tell, the most useful usages are:
Virtual destructor. If class has nothing except destructor, you can make it abstract by making destructor pure virtual. However, destructor needs a body in order to work.
"force conscious acceptance of default behavior". You provide body but derived class must explicitly call it.
"prevent creation of class instances". I.e. you provide function body, but prevent creation of class instance by making it abstract. You could do same thing by making constructor protected, though.
To provide default function body for diagnostical purposes - in case you somehow end up calling pure virtual function, it could print/log a diagnostical message somewhere.
In my opinion, you may run into pure virtual destructor eventually, and it is probably the most common use of this language feature.
Code:
class A{
public:
virtual ~A() = 0;
};
A::~A(){}//<-- comment this out and see what happens
class B: public A{
};
int main(int argc, char** argv){
B b;
return 0;
}
It just takes careful planning ... to go "far enough to be useful" in abstracting your design, without "building a hole for your project to fall into."
If you define a "pure virtual function in an abstract class," then what you're saying is that every descendent class [i]must[/u] define an implementation for this function. The compiler will obligingly prevent you from doing otherwise.
Some designers argue that you should "implement a do-nothing function, designed to be overridden, that blows-up if it is actually called." The problem here being that the compiler can't prevent you from writing code that calls the bomb, thus turning what could be a compile-time error into a run-time error.
In my humble, there is no bright-line rule here. It's your project, therefore your decision, just try to think ahead as far as you can. If you can reasonably think of a case where this-or-that function would not properly be implemented by a descendent class, then you probably need to re-consider your rules.
Actually my question was about *defining* the pure virtual
function in the *abstract base* class. I don't see anything
like that in your example.
You are correct; what would be the purpose of declaring a function as pure-virtual if the intent is to define a default implementation? If the plan is to provide a default implementation, then the function should be declared as virtual (not pure-virtual). It would be nice if the compiler would issue a warning if/when one defines a function that was previously declared as a pure-virtual function.
Last edited by dwhitney67; 11-09-2011 at 11:38 AM.
Declaring is enough (in the *abstract base* class), definition is not necessary, AFAIK.
I gave you "pure virtual destructor example" in post #7. Have you tried compiling with "A::~A(){}" commented out as was suggested in the comment? It looks like you haven't. Well, you should have given it a try. Compiling it without "A::~A(){}" will create unresolved external error on both g++/cl.exe, and it will not be possible to create instance of any class that inherits from "A". So "only declaring" is not always enough.
As for the rest of the issue (I.e. "pure virtual function (that is not a destructor) with a body") I think it is a matter of taste. It is possible that there's a scenario (aside from pure virtual destructor) when this feature is absolutely necessary.
Very helpful links. I'll look around more carefully next time before posting.
Pure virtual destructor was a new thing, although I couldn't find any more
uses of it.
Quote:
Originally Posted by SigTerm
In my opinion, you may run into pure virtual destructor eventually, and it is probably the most common use of this language feature.
You meant the most common use of the pure virtual destructor is to make
a class abstract without a dummy pure virtual function?
P.S.
That day I didn't read your detailed replies since didn't have enough
time. Thanks for your great help.
"what is the purpose/use of pure virtual methods in base class". "Define" does not obviously mean "function with a body", and I often confuse define/declare. Looks like few other people misread your question in similar fashion.
Quote:
Originally Posted by Anisha Kaul
You meant the most common use of the pure virtual destructor is to make
a class abstract without a dummy pure virtual function?
I'm not sure about "most common use", but it is the most obvious possible use of virtual abstract method with a body. Few guys on SO claim that it is "the most common", but I don't remember actually seeing such pattern in live code, so I'm not sure. Maybe i haven't noticed it, though.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.