Boost logo

Boost :

From: Vladislav Lazarenko (snail_at_[hidden])
Date: 2006-04-08 09:07:07


Dear colleagues, there is a version of sealed C++ class written with things
described in article "http://www.cuj.com/documents/s=8943/cujexp0312wilson2/" by
  Matthew Wilson taken into account. Please review.

Thank you in advance for you interest and time taken for review and discussion.

Here is a template friends workaround for different compilers.
Special thanks to Matthew Wilson. I decided to move it to the separated file
because it can be reused many times.

//
// Copyright (c) 2006 Matthew Wilson <matthew_at_[hidden]>
// Copyright (c) 2006 Vladislav Lazarenko <snail_at_[hidden]>
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TEMPLATE_FRIEND_HPP
#define BOOST_TEMPLATE_FRIEND_HPP

// MS compatible compilers support #pragma once.
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#if defined(__BORLANDC__) || \
     defined(__COMO__) || \
     defined(__DMC__) || \
     (defined(__GNUC__) && __GNUC__ < 3) || \
     defined(__INTEL_COMPILER) || \
     defined(__WATCOMC__) || \
     defined(_MSC_VER)
# define BOOST_DECLARE_TEMPLATE_FRIEND(T) friend T
#elif defined(__MWERKS__)
# define BOOST_DECLARE_TEMPLATE_FRIEND(T) friend class T
#elif defined(__GNUC__) && __GNUC__ >= 3
# define BOOST_DECLARE_TEMPLATE_FRIEND(T) \
   namespace boost { namespace template_friend { \
     struct friend_maker { \
       typedef T T2; \
     }; \
     typedef typename friend_maker::T2 friend_type; \
     friend friend_type;
#endif

#endif

And here is sealed class template themselves.

//
// Copyright (c) 2006 Vladislav Lazarenko <snail_at_[hidden]>
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_SEALED_HPP
#define BOOST_SEALED_HPP

// MS compatible compilers support #pragma once.
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/template_friend.hpp>

namespace boost
{
   // protection from unintended ADL
   namespace sealed_
   {
     template <typename T1, typename T2>
     class sealed_impl
     {
       BOOST_DECLARE_TEMPLATE_FRIEND(T1);
       BOOST_DECLARE_TEMPLATE_FRIEND(T2);

     private:
       /*
         NOTE TO USER:

         Compile error from here indicates that you has specified sealed class
         as the base class of another class.

         The sealed classes is used to prevent derivation from a class.
         An error occurs if a sealed class is specified as the base class of
         another class. A sealed class cannot also be an abstract class.
        */
       sealed_impl() {}
       ~sealed_impl() {}
     };
   }

   /*!
       The sealed classes is used to prevent derivation from a class.
       An error occurs if a sealed class is specified as the base class of
another class.
       A sealed class cannot also be an abstract class.
   */
   template <typename T>
   class sealed : virtual private sealed_::sealed_impl<sealed, T>
   {
   public:
     //! Constructor.
     sealed() {}

     //! Destructor.
     ~sealed() {}
   };

   /*
       Usage example:

       class UniquePerson : public boost::sealed<UniquePerson> // It is
impossible to inherit UniquePerson class.
       {
       public:
         UniquePerson() {}
         ~UniquePerson() {}
       };
   */
}

#endif


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk