This is the set/get class I use:
Code:
namespace Stuff
{
template<typename Type, typename Class, typename ReturnType = Type> class CUtilityMember
{
private:
Type Data;
typedef const ReturnType& (Class::*GetFncPointer)();
typedef void (Class::*SetFncPointer)(const Type& NewData);
GetFncPointer m_pGet;
SetFncPointer m_pSet;
Class* m_pClass;
public:
CUtilityMember(Class* pClass, GetFncPointer pGet = NULL, SetFncPointer pSet = NULL);
CUtilityMember(const Type& NewData, Class* pClass, GetFncPointer pGet = NULL, SetFncPointer pSet = NULL);
CUtilityMember& operator = (const Type& NewData);
operator Type () const;
};
template<typename Type, typename Class, typename ReturnType> CUtilityMember<Type, Class, ReturnType>::CUtilityMember
(Class* pClass, GetFncPointer pGet, SetFncPointer pSet): m_pClass(pClass), m_pGet(pGet), m_pSet(pSet) { }
template<typename Type, typename Class, typename ReturnType> CUtilityMember<Type, Class, ReturnType>::CUtilityMember
(const Type& NewData, Class* pClass, GetFncPointer pGet, SetFncPointer pSet): Data(NewData), m_pClass(pClass),
m_pGet(pGet), m_pSet(pSet) { }
template<typename Type, typename Class, typename ReturnType> CUtilityMember<Type, Class, ReturnType>& CUtilityMember
<Type, Class, ReturnType>::operator = (const Type& NewData)
{
if (m_pSet)
(m_pClass->*m_pSet)(NewData);
else
Data = NewData;
return *this;
}
template<typename Type, typename Class, typename ReturnType> CUtilityMember<Type, Class, ReturnType>::operator
Type () const
{
if (m_pGet)
return (m_pClass->*m_pGet)();
else
return Data;
}
}
Then I can do like this (see that they are added just like normal variables, but requires initialization):
Code:
#pragma warning(push)
#pragma warning(disable: 4355)
class CFilter
{
public:
CFilter(Strings::CStringEx strExt = _T(""), Strings::CStringEx strDescription = _T("")): strExt(strExt, this),
strDescription(strDescription, this) { }
CUtilityMember<Strings::CStringEx, CFilter> strExt;
CUtilityMember<Strings::CStringEx, CFilter> strDescription;
};
#pragma warning(pop)
And:
Code:
CFilter filter;
filter.strExt = "*.mkv";
filter.strDescription = "Matroska file";
cout << "File extension is: " << filter.strExt << endl;
cout << "File description is: " << filter.strDescription << endl;
Obviously it has a small overhead, but nothing significant.
(Some lines have been wrapped to avoid having to scroll.)
Although I'm sure some of the class could be improved (less memory overhead, for example).