C++ final class and slicing idiom - c++

I happened to be browsing the source for mongoDB, and found this interesting construct:
class NonspecificAssertionException final : public AssertionException {
public:
using AssertionException::AssertionException;
private:
void defineOnlyInFinalSubclassToPreventSlicing() final {}
};
How does the private method prevent slicing? I can't seem to think of the problem case.
Cheers, George

The only member functions to which the final specifier may be applied are virtual member functions. It is likely that in AssertionException or one of it's own base classes, this member is defined as
virtual void defineOnlyInFinalSubclassToPreventSlicing() = 0;
Thus, all classes in the hierarchy save the most derived ones are abstract base classes. One may not create values of abstract classes (they can only serve as bases). And so, one may not accidentally write
try {
foo();
}
catch(AssertionException const e) { // oops catching by value
}
If AssertionException was not abstract, the above could be written. But when it's abstract the compiler will complain at that exception handler, forcing us to catch by reference. And catching by reference is recommended practice.
Marking the member (and class) as final ensures no further derivation is possible. So the problem cannot reappear accidentally when the inheritance hierarchy is changed. Because a programmer that adds another class and again defines defineOnlyInFinalSubclassToPreventSlicing as final will elicit an error from the compiler, on account of this member already being declared final in the base. They will therefore have to remove the implementation from the base class, thus making it abstract again.
It's a bookkeeping system.

Related

Is the final function specifier redundant when using the final class specifier?

Is there any reason to specify a function as final when the class is already final? Or is that redundant?
class B
{
public:
virtual void f();
};
class D final : public B
{
public:
virtual void f() final; // Redundant final?
};
Would it be a good rule of thumb to say: Start with making the whole class final, and only switch to making individual functions final when you need to derive from the class and/or override specific functions?
It is definitely redundant because marking whole class as final makes it impossible to derive from this class and therefore override anything.
9 Classes [class]
If a class is marked with the class-virt-specifier final and it appears as a base-type-specifier in a base-clause
(Clause 10), the program is ill-formed.
So compiler won't even bother to check whether class deriving from final class actually tries to override anything or not.
No, it is not redundant, because final means different things when applied to classes and methods.
When final is applied to a class, it means that the class may not appear in the base-specifier-list of another class (i.e. you can't inherit from it)
When final is applied to a member function, it means that the function must be virtual in an ancestor class, and further specifies that it may not be overridden in a descendant class.
The key distinction is that final on a member function says that you must be overriding a virtual method in an ancestor class- if you're not, the compiler throws an error. When applied to a member function, final is basically an extension of the override keyword.
Applying final to methods can be very helpful in catching subtle bugs that would not be caught if you only specify final on the class.
Example 1: If you have misspelled the function name, or have not perfectly reproduced the parameter list, the function isn't actually overriding the base function and isn't going to be called when you think it's going to be called. But if you have specified that the function is final (or override) the compiler will detect that you are not successfully overriding a base function, and will throw an error. If you have only specified that the class is final, the compiler won't care that your function isn't actually overriding a virtual function, and won't throw an error.
Example 2: If you specify that a member function is final and the function signature in the base class changes (e.g. someone makes changes to the base class after you've tested and checked in your code), the compiler will helpfully point out that the base function is no longer being overridden by your function.

Is it bad practice to call a virtual function from constructor of a class that is marked final

Normally calling virtual functions from constructors is considered bad practice, because overridden functions in sub-objects will not be called as the objects have not been constructed yet.
But, Consider the following classes:
class base
{
public:
base() {}
~base() {}
private:
virtual void startFSM() = 0;
};
class derived final : public base
, public fsm_action_interface
{
public:
derived() : base{}
, theFSM_{}
{ startFSM(); }
/// FSM interface actions
private:
virtual void startFSM()
{ theFSM_.start(); }
private:
SomeFSMType theFSM_;
}
In this case class derived is marked as final so no o further sub-objects can exist. Ergo the virtual call will resolve correctly (to the most derived type).
Is it still considered bad practice?
This would still be considered bad practice as this sort of this almost always indicates bad design. You'd have to comment the heck out of the code to explain why this works in this one case.
T.C.'s comment above reinforces one of the reasons why this is considered bad practice.
What happens if, a year down the line, you decide that derived
shouldn't be final after all?
That said, in the example above, the pattern will work without issue. This is because the constructor of the most derived type is the one calling the virtual function. This problem manifests itself when a base class's constructor calls a virtual function that resolves to a subtype's implementation. In C++, such a function won't get called, because during base class construction, such calls will never go to a more derived class than that of the currently executing constructor or destructor. In essence, you end up with behavior you didn't expect.
Edit:
All (correct/non-buggy) C++ implementations have to call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail.
Scott Meyers also weighs in on the general issue of calling virtual functions from constructors and destructors in Effective C++ Item 9
Regarding
” Normally calling virtual functions from constructors is considered bad practice, because overridden functions in sub-objects will not be called as the objects have not been constructed yet.
That is not the case. Among competent C++ programmers it’s normally not regarded as bad practice to call virtual functions (except pure virtual ones) from constructors, because C++ is designed to handle that well. In contrast to languages like Java and C#, where it might result in a call to a method on an as yet uninitialized derived class sub-object.
Note that the dynamic adjustment of dynamic type has a runtime cost.
In a language oriented towards ultimate efficiency, with "you don't pay for what you don't use" as a main guiding principle, that means that it's an important and very much intentional feature, not an arbitrary choice. It's there for one purpose only. Namely to support those calls.
Regarding
” In this case class derived is marked as final so no o further sub-objects can exist. Ergo the virtual call will resolve correctly (to the most derived type).
The C++ standard guarantees that at the time of construction execution for a class T, the dynamic type is T.
Thus there was no problem about resolving to incorrect type, in the first place.
Regarding
” Is it still considered bad practice?
It is indeed bad practice to declare a member function virtual in a final class, because that’s meaningless. The “still” is not very meaningful either.
Sorry, I didn't see that the virtual member function was inherited as such.
Best practice for marking a member function as an override or implementation of pure virtual, is to use the keyword override, not to mark it as virtual.
Thus:
void startFSM() override
{ theFSM_.start(); }
This ensures a compilation error if it is not an override/implementation.
It can work, but why does startFSM() need to be virtual? In no case do you actually want to actually call anything but derived::startFSM(), so why have any dynamic binding at all? If you want to have it call the same thing as a dynamically binded method, make another non-virtual function called startFSM_impl() and have both the constructor and startFSM() call it instead.
Always prefer non-virtual to virtual if you can help it.

C++ should I use virtual methods?

Let me start by telling that I understand how virtual methods work (polymorphism, late-binding, vtables).
My question is whether or not I should make my method virtual. I will exemplify my dilemma on a specific case, but any general guidelines will be welcomed too.
The context:
I am creating a library. In this library I have a class CallStack that captures a call stack and then offers vector-like access to the captured stack frames. The capture is done by a protected method CaptureStack. This method could be redefined in a derived class, if the users of the library wish to implement another way to capture the stack. Just to be clear, the discussion to make the method virtual applies only to some methods that I know can be redefined in a derived class (in this case CaptureStack and the destructor), not to all the class methods.
Throughout my library I use CallStack objects, but never exposed as pointers or reference parameters, thus making virtual not needed considering only the use of my library.
And I cannot think of a case when someone would want to use CallStack as pointer or reference to implement polymorphism. If someone wants to derive CallStack and redefine CaptureStack I think just using the derived class object will suffice.
Now just because I cannot think polymorphism will be needed, should I not use virtual methods, or should I use virtual regardless just because a method can be redefined.
Example how CallStack can be used outside my library:
if (error) {
CallStack call_stack; // the constructor calls CaptureStack
for (const auto &stack_frame : call_stack) {
cout << stack_frame << endl;
}
}
A derived class, that redefines CaptureStack could be use in the same manner, not needing polymorphism:
if (error) {
// since this is not a CallStack pointer / reference, virtual would not be needed.
DerivedCallStack d_call_stack;
for (const auto &stack_frame : d_call_stack) {
cout << stack_frame << endl;
}
}
If your library saves the call stack during the constructor then you cannot use virtual methods.
This is C++. One thing people often get wrong when coming to C++ from another language is using virtual methods in constructors. This never works as planned.
C++ sets the virtual function table during each constructor call. That means that functions are never virtual when called from the constructor. The virtual method always points to the current class being constructed.
So even if you did use a virtual method to capture the stack the constructor code would always call the base class method.
To make it work you'd need to take the call out of the constructor and use something like:
CallStack *stack = new DerivedStack;
stack.CaptureStack();
None of your code examples show a good reason to make CaptureStack virtual.
When deciding whether you need a virtual function or not, you need to see if deriving and overriding the function changes the expected behavior/functionality of other functions that you're implementing now or not.
If you are relying on the implementation of that particular function in your other processes of the same class, like another function of the same class, then you might want to have the function as virtual. But if you know what the function is supposed to do in your parent class, and you don't want anybody to change it as far as you're concerned, then it's not a virtual function.
Or as another example, imagine somebody derives a class from you implementation, overrides a function, and passes that object as casted to the parent class to one of your own implemented functions/classes. Would you prefer to have your original implementation of the function or you want them to have you use their own overriden implementation? If the latter is the case, then you should go for virtual, unless not.
It's not clear to me where CallStack is being called. From
your examples, it looks like you're using the template method
pattern, in which the basic functionality is implemented in the
base class, but customized by means of virtual functions
(normally private, not protected) which are provided by the
derived class. In this case (as Peter Bloomfield points out),
the functions must be virtual, since they will be called from
within a member function of the base class; thus, with a static
type of CallStack. However: if I understand your examples
correctly, the call to CallStack will be in the constructor.
This will not work, as during construction of CallStack, the
dynamic type of the object is CallStack, and not
DerivedCallStack, and virtual function calls will resolve to
CallStack.
In such a case, for the use cases you describe, a solution using
templates may be more appropriate. Or even... The name of the
class is clear. I can't think of any reasonable case where
different instances should have different means of capturing the
call stack in a single program. Which suggests that link time
resolution of the type might be appropriate. (I use the
compilation firewall idiom and link time resolution in my own
StackTrace class.)
My question is whether or not I should make my method virtual. I will exemplify my dilemma on a specific case, but any general guidelines will be welcomed too.
Some guidelines:
if you are unsure, you should not do it. Lots of people will tell you that your code should be easily extensible (and as such, virtual), but in practice, most extensible code is never extended, unless you make a library that will be used heavily (see YAGNI principle).
you can use encapsulation in place of inheritance and type polymorphism (templates) as an alternative to class hierarchies in many cases (e.g. std::string and std::wstring are not two concrete implementations of a base string class and they are not inheritable at all).
if (when you are designing your code/public interfaces) you realize you have more than one class that "is an" implementation of another classes' interface, then you should use virtual functions.
You should almost certainly declare the method as virtual.
The first reason is that anything in your base class which calls CaptureStack will be doing so through a base class pointer (i.e. the local this pointer). It will therefore call the base class version of the function, even though a derived class masks it.
Consider the following example:
class Parent
{
public:
void callFoo()
{
foo();
}
void foo()
{
std::cout << "Parent::foo()" << std::endl;
}
};
class Child : public Parent
{
public:
void foo()
{
std::cout << "Child::foo()" << std::endl;
}
};
int main()
{
Child obj;
obj.callFoo();
return 0;
}
The client code using the class is only ever using a derived object (not a base class pointer etc.). However, it's the base class version of foo() that actually gets called. The only way to resolve that is to make foo() virtual.
The second reason is simply one of correct design. If the purpose of the derived class function is to override rather than mask the original, then it should probably do so unless there is a specific reason otherwise (such as performance concerns). If you don't do that, you're inviting bugs and mistakes in future, because the class may not act as expected.

Private virtual method in C++

What is the advantage of making a private method virtual in C++?
I have noticed this in an open source C++ project:
class HTMLDocument : public Document, public CachedResourceClient {
private:
virtual bool childAllowed(Node*);
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
};
Herb Sutter has very nicely explained it here.
Guideline #2: Prefer to make virtual functions private.
This lets the derived classes override the function to customize the
behavior as needed, without further exposing the virtual functions
directly by making them callable by derived classes (as would be
possible if the functions were just protected). The point is that
virtual functions exist to allow customization; unless they also need
to be invoked directly from within derived classes' code, there's no
need to ever make them anything but private
If the method is virtual it can be overridden by derived classes, even if it's private. When the virtual method is called, the overridden version will be invoked.
(Opposed to Herb Sutter quoted by Prasoon Saurav in his answer, the C++ FAQ Lite recommends against private virtuals, mostly because it often confuses people.)
Despite all of the calls to declare a virtual member private, the argument simply doesn't hold water. Frequently, a derived class's override of a virtual function will have to call the base class version. It can't if it's declared private:
class Base
{
private:
int m_data;
virtual void cleanup() { /*do something*/ }
protected:
Base(int idata): m_data (idata) {}
public:
int data() const { return m_data; }
void set_data (int ndata) { m_data = ndata; cleanup(); }
};
class Derived: public Base
{
private:
void cleanup() override
{
// do other stuff
Base::cleanup(); // nope, can't do it
}
public:
Derived (int idata): base(idata) {}
};
You have to declare the base class method protected.
Then, you have to take the ugly expedient of indicating via a comment that the method should be overridden but not called.
class Base
{
...
protected:
// chained virtual function!
// call in your derived version but nowhere else.
// Use set_data instead
virtual void cleanup() { /* do something */ }
...
Thus Herb Sutter's guideline #3...But the horse is out of the barn anyway.
When you declare something protected you're implicitly trusting the writer of any derived class to understand and properly use the protected internals, just the way a friend declaration implies a deeper trust for private members.
Users who get bad behavior from violating that trust (e.g. labeled 'clueless' by not bothering to read your documentation) have only themselves to blame.
Update: I've had some feedback that claims you can "chain" virtual function implementations this way using private virtual functions. If so, I'd sure like to see it.
The C++ compilers I use definitely won't let a derived class implementation call a private base class implementation.
If the C++ committee relaxed "private" to allow this specific access, I'd be all for private virtual functions. As it stands, we're still being advised to lock the barn door after the horse is stolen.
I first came across this concept while reading Scott Meyers' 'Effective C++', Item 35: Consider alternatives to virtual functions. I wanted to reference Scott Mayers for others that may be interested.
It's part of the Template Method Pattern via the Non-Virtual Interface idiom: the public facing methods aren't virtual; rather, they wrap the virtual method calls which are private. The base class can then run logic before and after the private virtual function call:
public:
void NonVirtualCalc(...)
{
// Setup
PrivateVirtualCalcCall(...);
// Clean up
}
I think that this is a very interesting design pattern and I'm sure you can see how the added control is useful.
Why make the virtual function private? The best reason is that we've already provided a public facing method.
Why not simply make it protected so that I can use the method for other interesting things? I suppose it will always depend on your design and how you believe the base class fits in. I would argue that the derived class maker should focus on implementing the required logic; everything else is already taken care of. Also, there's the matter of encapsulation.
From a C++ perspective, it's completely legitimate to override a private virtual method even though you won't be able to call it from your class. This supports the design described above.
I use them to allow derived classes to "fill in the blanks" for a base class without exposing such a hole to end users. For example, I have highly stateful objects deriving from a common base, which can only implement 2/3 of the overall state machine (the derived classes provide the remaining 1/3 depending on a template argument, and the base cannot be a template for other reasons).
I NEED to have the common base class in order to make many of the public APIs work correctly (I'm using variadic templates), but I cannot let that object out into the wild. Worse, if I leave the craters in the state machine- in the form of pure virtual functions- anywhere but in "Private", I allow a clever or clueless user deriving from one of its child classes to override methods that users should never touch. So, I put the state machine 'brains' in PRIVATE virtual functions. Then the immediate children of the base class fill in the blanks on their NON-virtual overrides, and users can safely use the resulting objects or create their own further derived classes without worrying about messing up the state machine.
As for the argument that you shouldn't HAVE public virtual methods, I say BS. Users can improperly override private virtuals just as easily as public ones- they're defining new classes after all. If the public shouldn't modify a given API, don't make it virtual AT ALL in publicly accessible objects.

Is it possible to forbid deriving from a class at compile time?

I have a value class according to the description in "C++ Coding Standards", Item 32. In short, that means it provides value semantics and does not have any virtual methods.
I don't want a class to derive from this class. Beside others, one reason is that it has a public nonvirtual destructor. But a base class should have a destructor that is public and virtual or protected and nonvirtual.
I don't know a possibility to write the value class, such that it is not possible to derive from it. I want to forbid it at compile time. Is there perhaps any known idiom to do that? If not, perhaps there are some new possibilities in the upcoming C++0x? Or are there good reasons that there is no such possibility?
Bjarne Stroustrup has written about this here.
The relevant bit from the link:
Can I stop people deriving from my class?
Yes, but why do you want to? There are two common answers:
for efficiency: to avoid my function
calls being virtual.
for safety: to ensure that my class is not used as a
base class (for example, to be sure
that I can copy objects without fear
of slicing)
In my experience, the efficiency reason is usually misplaced fear. In C++, virtual function calls are so fast that their real-world use for a class designed with virtual functions does not to produce measurable run-time overheads compared to alternative solutions using ordinary function calls. Note that the virtual function call mechanism is typically used only when calling through a pointer or a reference. When calling a function directly for a named object, the virtual function class overhead is easily optimized away.
If there is a genuine need for "capping" a class hierarchy to avoid virtual function calls, one might ask why those functions are virtual in the first place. I have seen examples where performance-critical functions had been made virtual for no good reason, just because "that's the way we usually do it".
The other variant of this problem, how to prevent derivation for logical reasons, has a solution. Unfortunately, that solution is not pretty. It relies on the fact that the most derived class in a hierarchy must construct a virtual base. For example:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
(from D&E sec 11.4.3).
If you are willing to only allow the class to be created by a factory method you can have a private constructor.
class underivable {
underivable() { }
underivable(const underivable&); // not implemented
underivable& operator=(const underivable&); // not implemented
public:
static underivable create() { return underivable(); }
};
Even if the question is not marked for C++11, for people who get here it should be mentioned that C++11 supports new contextual identifier final. See wiki page
Take a good look here.
It's really cool but it's a hack.
Wonder for yourself why stdlib doesn't do this with it's own containers.
Well, i had a similar problem. This is posted here on SO. The problem was other way around; i.e. only allow those classes to be derived that you permit. Check if it solves your problem.
This is done at compile-time.
I would generally achieve this as follows:
// This class is *not* suitable for use as a base class
The comment goes in the header and/or in the documentation. If clients of your class don't follow the instructions on the packet, then in C++ they can expect undefined behavior. Deriving without permission is just a special case of this. They should use composition instead.
Btw, this is slightly misleading: "a base class should have a destructor that is public and virtual or protected and nonvirtual".
That's true for classes which are to be used as bases for runtime polymorphism. But it's not necessary if derived classes are never going to be referenced via pointers to the base class type. It might be reasonable to have a value type which is used only for static polymorphism, for instance with simulated dynamic binding. The confusion is that inheritance can be used for different purposes in C++, requiring different support from the base class. It means that although you don't want dynamic polymorphism with your class, it might nevertheless be fine to create derived classes provided they're used correctly.
This solution doesn't work, but I leave it as an example of what not to do.
I haven't used C++ for a while now, but as far as I remember, you get what you want by making destructor private.
UPDATE:
On Visual Studio 2005 you'll get either a warning or an error. Check up the following code:
class A
{
public:
A(){}
private:
~A(){}
};
class B : A
{
};
Now,
B b;
will produce an error "error C2248: 'A::~A' : cannot access private member declared in class 'A'"
while
B *b = new B();
will produce warning "warning C4624: 'B' : destructor could not be generated because a base class destructor is inaccessible".
It looks like a half-solutiom, BUT as orsogufo pointed, doing so makes class A unusable. Leaving answers