
I am very proud to see that a few people were interested in my proposal. I know that in the C++ programming language it is very unusual to define a class to be final....but I have to say that I wrote my tool mostly in order to understand certain low level mechanisms, which are involved in the "nonderivable" implementation. A few days ago I found a backdoor in my code, since a compiler would allow to subclass a final class simply by reapplying the BOOST_NON_DERIVABLE macro as follows: class Foo : BOOST_NON_DERIVABLE { }; class Goo : public Foo, BOOST_NON_DERIVABLE { }; Goo goo; // Compiles I first tried to reimplement the library from scratch, but later I realized that it was sufficient to prohibit that a class can derive twice from "nonderivable". In the new implementation, I use a smart trick, which may be explained as follows: I added a pure virtual method , called uniqueness, to the virtual base class nonderivable_helper, then in the intermediate class, called nonderivable, I override it with an empty function....note that the BOOST_NON_DERIVABLE makes the user to derive from the nonderivable....then if you try to subclass twice nonderivable (which is not virtual), then you have only one nonderivable_helper sub object (since it is a virtual base class) and two (o more) final overrider for the nonderivable_helper::uniqueness method, one for each nonderivable sub object. As expected, this causes a compilation error when I use GCC 4.1. If this mechanisms were portable (I ask other users for a test), I think this implementation should be 100% standard compliant and very strong. I developed this library independently and I didn't know that there was a similar tool (called noninheritable) in the Vault in the folder Generic Programming....I make you note that the library are very different: indeed, I believe (?) I used only standard facilities and that there could be interesting techniques in my work (.....I hope there is not another work in the vault :) Best Regards, Manuel Fiorelli www.fioreltech.net 2007/3/5, Noah Roberts <roberts.noah@gmail.com>:
I thank you a lot for the suggestions and I want to say that:
- I kept the original idea from Java Core Vol. 1 (by Cay Horstmann), where the author states that in C++ there aren't final classes, but
Manuel Fiorelli wrote: they
could be simulated through virtual inheritance....thus I tried to discovery that trick. - there is no reason to use a protected destructor; since I use private inheritance, automatic conversion of pointers from the derived class to the base class isn't possible, thus there is no reason to prevent accidental delete trough base class pointers...I realized it only after the submission... - unfortunately, I just discovered that the following code compiles (violating the "non derivable" semantics)
struct Foo : BOOST_NON_DERIVABLE {
};
struct Goo : public Foo, BOOST_NON_DERIVABLE {
};
Foo foo; // a variant or a class member Goo goo;
But they have to purposefully violate the documented semantic use of the class. This is good IMHO. You've told the user, "Don't try this," and they're saying, "Well, I'm going to do it anyway." They know they aren't supposed to...they're on their own. You can, and should, only do so much semantic enforcement in C++.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost