Re: CString ... are 'they' nuts?
On Thu, 5 Feb 2009 11:57:10 -0800 (PST), ".rhavin grobert" <clqrq@yahoo.de>
wrote:
On 4 Feb., 18:13, ".rhavin grobert" <cl...@yahoo.de> wrote:
that leads me to the question: can i derive from CString if the only
thing i do is overload the operator=()...
My solution...
//-----------------------------------------------------------------------------
class CQString : public CString
{
public:
// overloaded contructors refer to baseclass
inline CQString() {};
inline CQString(const CString& stringSrc) : CString(stringSrc) {};
inline CQString(LPCTSTR lpsz) : CString(lpsz) {};
#ifdef _UNICODE
inline CQString(LPCSTR lpsz) : CString(lpsz) {};
#else
inline CQString(LPCWSTR lpsz) : CString(lpsz) {};
#endif
// additional constructor for resource-id's
inline CQString(UINT nRscID) {LoadString(nRscID);};
// destructor does nothing
virtual inline ~CQString() {};
// the only real overload, we need to check for ResourceID
const CQString& operator=(LPCTSTR lpsz);
};
There are several problems with this:
1. The following behave very differently:
CString x('a');
CQString x('a');
The first one does what is expected for a string class; it constructs a
string equal to 'a'. The second one does something bizarre.
2. Your comment notwithstanding, you're not overloading operator=. In fact,
your operator= is the only one your class has. It accepts CStrings due to
CString's conversion operator, and assignment to a CQString will never
benefit from CString's reference-counting. You would work around this
problem with a using-declaration, but the return types would remain
CString&, which is wrong. The proper way is to add the CString operator=
signatures by hand, including the copy-assignment operator, changing the
return type to CQString&.
3. The semicolons following the end-brackets of function definitions are
not necessary and should not be used.
4. CString has no virtual functions, and it is bad practice to derive
publicly from it. The traditional objection is that is undefined to delete
a CQString through a pointer to its CString base. Perhaps more importantly,
you will probably start writing interfaces in terms of CQString. Passing a
CString where a CQString is required makes a copy of the CString; this is
inefficient (though mitigated by reference-counting) for CQString const
reference parameters and is incompatible with CQString non-const reference
parameters. Furthermore, suppose you mix your code with similar code that
uses CXString. There will probably be some functions f(CXString), and you
cannot pass your CQStrings to them.
5. There's no legitimate reason for CQString to exist. The CString class
already provides the LoadString function and a ctor that takes a resource
ID cast to a string, and they are what you should use.
--
Doug Harrison
Visual C++ MVP