Topic: final classes


Author: nospam@slack.net (ant)
Date: 1999/07/15
Raw View
In article <378CEB11.13E143CE@tribble.com>, David R Tribble
<david@tribble.com> wrote:

> Alex Oren wrote:
> >
> > In "Re: Question about delete" Andrei Alexandrescu
> > <andrewalex@hotmail.com> wrote:
> >
> > } I bet in this case the first and most used idiom for this hack would
> > } be to create final classes, e.g.:
> > }
> > } class FinalClass // not intended to be derived from
> > } {
> > }     ...
> > }     char unused[];
> > } };
> > }
> > } Given that the only current method for creating final classes is via
> > } the virtual base hack, that would be an interesting alternative.
> >
> > Please elaborate on the "virtual base hack".
>
> He's probably referring to the fact that you can't create a derived
> object if its base class has a private (inaccessible) constructor or
> destructor.  Of course, this means you can't create an object of the
> base class type, either.

VIRTUAL base hack. You didn't mention virtual anywhere :-)  That isn't the
idea. Here are my notes on it:

Basic idea:

    class Final {
    private:
        Final() { }
        friend class Foo;
    };

    class Foo : virtual Final {
    };

Only Foo can invoke ctor for Final. Virtual bases are constructed by the
complete object type's ctor, so anything derived from Foo won't be able to
construct its virtual Final base class (since its ctor is private).

Now, we want to make it convenient for general use. Let's templatize the
base class:

    template<class T>
    class final {
    private:
        final() { }
        friend class T;
    };

    // Foo is final
    class Foo : virtual final<Foo> {
    };

Let's not require the user to specify it a virtual base (as opposed to
regular base), because leaving this out wouldn't cause a compiler error,
but would allow derived classes. This may not be noticed.

    template<class T>
    class final;

    template<class T>
    class final_ {
    private:
        final_() { }
        friend class final<T>;
        friend class T;
    };

    template<class T>
    class final : private virtual final_<T> {
    private:
        final() { } // "T must derived from us" idiom
        friend class T;
    };

    // Foo is final
    class Foo : final<Foo> {
    };

    class Bad : public Foo {
        // illegal - can't construct final_
    };

    // just as an example, virtual inheritance doesn't matter
    // if it's accidentally put in
    class Bar : virtual final<Bar> {
        // OK, but virtual isn't necessary
    };

(it should be noted that the particular compiler I use doesn't enforce
much access control, so this idiom doesn't restrict anything on it
<shrug>)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/07/15
Raw View
In article <378CEB11.13E143CE@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
> Alex Oren wrote:
> >
> > In "Re: Question about delete" Andrei Alexandrescu
> > <andrewalex@hotmail.com> wrote:
> >
> > } I bet in this case the first and most used idiom for this hack
would
> > } be to create final classes, e.g.:
> > }
> > } class FinalClass // not intended to be derived from
> > } {
> > }     ...
> > }     char unused[];
> > } };
> > }
> > } Given that the only current method for creating final classes is
via
> > } the virtual base hack, that would be an interesting alternative.
> >
> > Please elaborate on the "virtual base hack".
>
> He's probably referring to the fact that you can't create a derived
> object if its base class has a private (inaccessible) constructor or
> destructor.  Of course, this means you can't create an object of the
> base class type, either.

No.  He's referring to a trick invented by Andy Koenig which effectively
prevents derivation.  A virtual base class is initialized by the most
derived class, which of course, must have access to its constructor to
do so.  So you define a dummy class with a private constructor, but
declare yourself as a friend of it, and inherit virtually from it.
Since the constructor is private, no one but you (who are a friend) can
access it.

--
James Kanze                         mailto:
James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                        Beratung in objekt orientierter
Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany  Tel. +49 (069) 63 19 86
27


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrei Alexandrescu <andrewalex@hotmail.com>
Date: 1999/07/15
Raw View
In article <nospam-1407992026090001@as3-dialup-16.io.com>,
  nospam@slack.net (ant) wrote:
[snip]
>     template<class T>
>     class final {
>     private:
>         final() { }
>         friend class T;
>     };

Alas, this is not doable as far as I know. You cannot make a parameter
template a friend class of your template.

Andrei


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/07/18
Raw View
Andrei Alexandrescu wrote:
>
> In article <nospam-1407992026090001@as3-dialup-16.io.com>,
>   nospam@slack.net (ant) wrote:
> [snip]
> >     template<class T>
> >     class final {
> >     private:
> >         final() { }
> >         friend class T;
> >     };
>
> Alas, this is not doable as far as I know.

template <class X>
class final {
    final () { }
    friend class X::U;
};

template <class Y>
struct Hold {
    typedef Y U;
};

class X : virtual final<Hold<X> > {};

gives me

/tmp/xyz.cc:4: `X' does not have a nested type named `U'
/tmp/xyz.cc:4: confused by earlier errors, bailing out

I don't know if it's correct or not.

> You cannot make a parameter
> template a friend class of your template.

...which is completly non-sensical and looks silly (and
is silly)

--

Valentin Bonnard


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: alexo@bigfoot---filter---.com (Alex Oren)
Date: 1999/07/12
Raw View
In "Re: Question about delete" Andrei Alexandrescu <andrewalex@hotmail.com> wrote:

} I bet in this case the first and most used idiom for this hack would be
} to create final classes, e.g.:
}
} class FinalClass // not intended to be derived from
} {
}     ...
}     char unused[];
} };
}
} Given that the only current method for creating final classes is via the
} virtual base hack, that would be an interesting alternative.

Please elaborate on the "virtual base hack".

Have fun,
Alex.

--

My email address is intentionally mangled to foil spambots.
Please remove the "---filter---" from the address for replying.
Sorry for the inconvenience.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 1999/07/15
Raw View
Alex Oren wrote:
>
> In "Re: Question about delete" Andrei Alexandrescu
> <andrewalex@hotmail.com> wrote:
>
> } I bet in this case the first and most used idiom for this hack would
> } be to create final classes, e.g.:
> }
> } class FinalClass // not intended to be derived from
> } {
> }     ...
> }     char unused[];
> } };
> }
> } Given that the only current method for creating final classes is via
> } the virtual base hack, that would be an interesting alternative.
>
> Please elaborate on the "virtual base hack".

He's probably referring to the fact that you can't create a derived
object if its base class has a private (inaccessible) constructor or
destructor.  Of course, this means you can't create an object of the
base class type, either.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]