Who is "you"?
Who is "you"?
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
The whole point of abstract is that they can only be derived and not be created, of course, but that doesn't mean it seems logical to make a pure virtual destructor since pure virtual functions aren't meant to be called. So far as I understand them, they only make a class abstract and thus needs to overriden within a derived class.
But it seems to me that this doesn't mean that you cannot provide an implementation for pure virtual methods and call it explicitly (from concrete derived classes) or implicitly (the destructor).So far as I understand them, they only make a class abstract and thus needs to overriden within a derived class.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Not really. The primary purpose of a pure virtual function is to make the class abstract (i.e. the class represents an abstraction, and instances of the class cannot be created). For pure virtual functions other than the destructor, derived classes must override any inherited virtual functions or they will remain abstract. Pure virtual destructors serve to ensure that the class cannot be instantiated, but destructors are special in the sense that ALL classes must have a defined (i.e. implemented) destructor and, if the programmer has declared a destructor, programmer must also define it. For example;
In practice, if Base::~Base() is not defined in the above, then the most common result is a linker error. The reason is that, when a Derived is destroyed, that Derived::~Derived is invoked and then Base::~Base() is invoked. However, Derived::~Derived() does not override Base::~Base() as both functions must existCode:class Base { public: virtual ~Base() = 0; // declaration of destructor // whatever }; Base::~Base() // definition of this destructor is required despite it being pure virtual {} class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {} int main() { Derived d; }
Coming back to the original question, default assignment can be used for const reference arguments, even for pure virtual functions. The requirements are that the default value has const attributes (eg it is a compile time constant), and that a conversion (eg conversion constructor) exists between the value given and the type of the argument. That's the theory: there is also practice -- such approaches are not a good idea with virtual functions, because derived classes may provide different default values than base classes, and therefore the result may not be what the programmer expects in some cases. Hence the value of techniques such the NVI pattern mentioned by CornedBee.
Last edited by grumpy; 11-29-2007 at 07:34 AM.
Yes, I know what they are and everything, and it's exactly as I described. If were create pure virtual functions to make sure a class can't be instaciated, then what's the point of defining them when they're always overriden by derived classes? I understand the NEED to do so, but I do not see a need to make a pure virutal destructor since, as you mentioned, they must be defined, but since it's a pure virtual function, it isn't supposed to be called, and thus it doesn't meet the define for my interpretation of a pure virtual function.
In short, it can be a pure virtual function, but that defeats the purpose of a pure virtual function in my book, or at least seems illogical or bends the rules as to why pure virtual functions were made an addition to the language.
Last edited by Elysia; 11-29-2007 at 07:37 AM.
I don't like to look at pure virtual functions meaning that they aren't supposed to be called.
I think a better description is that a pure virtual function means that the function must be overridden.
If you look at it that way then the pure virtual destructor and any other pure virtual function with an implementation makes sense. You are forcing classes that concretely implement your abstract interface to implement that function.
Indeed, and then what's the purpose of the pure virtual function if it's overriden and isn't called?
But your reply made me think of something. It might still be possible to use the base class's function as a base - base code that is the same for all derived classes, and since it's a base class not suppoed to be instanciated, it can be declared a pure virtual, and the derived classes override, do some work and call the base class's function. I suppose that might be a valid idea.
I haven't used it myself, but I guess one motivation for making a function pure virtual and still providing an implementation (as default behaviour for the hierarchy) is to ensure that the writer of the derived class explicitly states that he want's to use the default behaviour (and not get the default behaviour accidentally because he forgot to override this method).
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
I think anon was contrasting default implementations with pure virtual functions versus default implementations with virtual functions.Eh? If someone forgets to override the function, you'll get an abstract derived class and the code won't compile.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Sorry if it bothers you. I guess languages reflect the chauvinist history of mankind and I even try to use the neutral singular "they" sometimes, but I guess it would be easier to accept that
and stop raping the languagehe ... 2. used to talk about anyone, everyone, or an unknown person who may be either male or female
(Longman)
Yes, but you may want to provide a default implementation that has to be called explicitly.Eh? If someone forgets to override the function, you'll get an abstract derived class and the code won't compile.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
I've given example code with an implementation of a pure virtual function, have I not?
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
Yes, but I think Elysia was still confused about the usefulness.
Well, having a default implementation even of pure virtual functions is useful if there's stuff that most overriding functions have to do. (But not if all overriding functions have to do it - to enforce this, use the NVI pattern.)
The destructor thing is, admittedly, something of a hack. It's like a Java class with the abstract modifier but no abstract functions. You can't instantiate the class itself, but you can instantiate a subclass, even if it did nothing but derive.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law