Sunday, June 19, 2011

C++ final function solution

Simple explanation:

class FinalMethod1 { //all methods private
friend class ClassWithFinalMethod; 
// friend ClassWithFinalMethod ::theFinalMethod(); //this method also works but is not as portable.
FinalMethod1(){}
 FinalMethod1(const FinalMethod1& );
 FinalMethod1& operator=(const FinalMethod1& );
};

struct Base { //only ClassWithFinalMethod can override this one.
 virtual FinalMethod1 theFinalMethod ()=0;
};

struct ClassWithFinalMethod : public Base
{
 virtual FinalMethod1 theFinalMethod () { return FinalMethod (); }
};

More comprehensive one with Boost that allow to generate N number of classes that will implement final function:

#include <boost/preprocessor/repetition.hpp>
//specify desired number of classes will be used by default.
#ifndef NUMBER_OF_SLOTS
#  define NUMBER_OF_SLOTS 4
#endif
#if NUMBER_OF_SLOTS<1
#  define NUMBER_OF_SLOTS 1
#endif

//if
//#include <boost/mpl/identity.hpp>
// is included.
#ifndef BOOST_MPL_IDENTITY_HPP_INCLUDED
struct nothing {
      typedef nothing type;
};
#define ADD_FRIEND(z,n,name) friend class name##n::type;
#else
//identity will provide type where needed.
struct nothing {};
#define ADD_FRIEND(z,n,name) friend class boost::mpl::identity<name##n>::type;
#end

//generic class that return some return value.
//May need specialization for & and * implementation.
template< typename ReturnType, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(NUMBER_OF_SLOTS, typename T, nothing) > class final
 {
 BOOST_PP_REPEAT( NUMBER_OF_SLOTS, ADD_FRIEND, T )
 ReturnType _result;
 final( ReturnType result ): _result(result) {}
 final( const final& );
public:
 inline operator ReturnType() { return _result; }
};

//specialization for void return value.
template< BOOST_PP_ENUM_PARAMS(NUMBER_OF_SLOTS,typename T) > class final <void, BOOST_PP_ENUM_PARAMS(NUMBER_OF_SLOTS,T) >
{
 BOOST_PP_REPEAT(NUMBER_OF_SLOTS,ADD_FRIEND,T)
 final( ) {}
 final( const final& ){}
};

No comments:

Post a Comment