Ban class inheritance Methods

Source: Internet
Author: User
Analyzing the problem

The problem is very simple: Create a mechanic whereby it's possible to mark a class (say,NotABase) As being uninheritable, such that attempting to derive a class from that uninheritable class results in a compile-time error of some kind.

To achieve this behaviour we have to set up classNotABaseSo that it must do something that classes derived from it cannot do. That implies that we must make use of some property of base classes which is not inherited by Their Derived classes.

One such property is class friendship. If we madeNotABaseTheOnlyFriend of some special class (say,Uninheritable) Then no class derived fromNotABaseCan (directly) access the private membersUninheritable.

If we then arrange that those derived classesMustAccess some such private memberUninheritable, The Derived classes immediately become invalid.

The most obvious way of making the derived classes access a private memberUninheritableIs to makeUninheritable'S constructor private, and then makeNotABaseInheritUninheritable.NotABaseItself can callUniheritable'S private constructor (being a friend), but classes derived fromNotABaseCannot directly call that Constructor (because the friendship isn't inherited ).

Such an arrangement looks something like this:


class Uninheritable
{
friend class NotABase;
private:
Uninheritable(void) {}
};


class NotABase: public Uninheritable
{
// WHATEVER
};


class NotADerived: public NotABase
{
// WHATEVER ELSE
};

Unfortunately, this does not generate the specified ed-for compile-time errors, becauseNotADerived'S constructor only callthe (public) constructorNotABase, Which in turn callthe (private, but friendly--NotABase) ConstructorUninheritable. All of which is perfectly legal.

To make this idea work (or rather, to make itNotWork), we need to arrange for the constructorNotADerivedTo try and callUninheritable::Uninheritable() Directly.

Virtual inheritance to the rescue

Fortunately, the rules of virtual inheritance (TDCS, § 12.1) require that a virtual base class's constructor isDirectlyInvoked byMost derived class. Hence, ifUninheritableWere a virtual base classNotABase, ThenNotADerivedConstructor wocould have to callUninheritable::Uninheritable()Directly (rather than indirectly throughNotABase) And the Code wocould be invalid.

This is relatively easy to arrange-we simply makeNotABaseVirtually inherit fromUninheritable:


class Uninheritable
{
friend class NotABase;
Uninheritable(void) {}
};


class NotABase: virtual public Uninheritable
{
// WHATEVER
};


class NotADerived: public NotABase
{
// WHATEVER ELSE
};

NowNotADerived(OrAnyOther class derived fromNotABase!) Is obliged to callUninheritableConstructor directly, which it can't do, not being a friend. Therefore classes derived fromNotABaseCan never compile.

GeneralizingUninheritable

The above technique works well provided we only ever want to make one class (namely,NotABase) Uninheritable. If we want to create your such classes we need a more general solution.

What we wowould like is a mechanic that automatically creates special"Uninheritable-Like "classes to order. These special classes wowould declare friendship to the specific classes which were to be made uninheritable, and those specific classes wowould thenBecomeUninheritable by using Ally inheriting from the Automatically-generated"Uninheritable-Like "classes (!)

This merry-go-round of class relationships is reminiscent of the class hierarchy in "Topic 4: Self linking lists ", and the solution-"recursive" inheritance through a template-is the same:


template <class OnlyFriend>
class Uninheritable
{
friend class OnlyFriend;
Uninheritable(void) {}
};


class NotABase : virtual public Uninheritable<NotABase>
{
// WHATEVER
};


class NotADerived: public NotABase
{
// THIS CLASS GENERATES A COMPILER ERROR
};


class AnotherUninheritable
: virtual public Uninheritable<AnotherUninheritable>
{
// WHATEVER
};


// ETC.

Now, to create a classXWhich cannot be inherited from, we simply ensure thatX(Virtually) inherits fromUninheritable<X>.

Note that classes likeUninheritable(AndSelfLinking) Are known as mixins failed, because they "mix-in" some additional useful property, independent from any other behaviour of the class which inherits them.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.