Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CString ... are 'they' nuts?

73 views
Skip to first unread message

.rhavin grobert

unread,
Feb 4, 2009, 12:08:13 PM2/4/09
to
The code between /* ### */ is - of course - not in the original ...
8-|


const CString& CString::operator=(LPCTSTR lpsz)
{
/* ### */
if (lpsz != NULL && HIWORD(lpsz) == NULL)
{
UINT nID = LOWORD((DWORD)lpsz);
if (!LoadString(nID))
TRACE1("Warning: implicit LoadString(%u) failed\n", nID);
return *this;
}
/* ### */

ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
AssignCopy(SafeStrlen(lpsz), lpsz);
return *this;
}

thanks microsoft!

.rhavin grobert

unread,
Feb 4, 2009, 12:13:30 PM2/4/09
to
that leads me to the question: can i derive from CString if the only
thing i do is overload the operator=() , or do i have to use a
container-class?

David Ching

unread,
Feb 4, 2009, 12:43:21 PM2/4/09
to
".rhavin grobert" <cl...@yahoo.de> wrote in message
news:1d623597-66c5-46f5...@i18g2000prf.googlegroups.com...


Passing a resource ID is supported in the CString ctor, but apparently not
in the operator =. How were you planning to use this capability? Like
this?

CString str;
str = MAKEINTRESOURCE(IDC_MY_STRING);

This is highly unusual. This code is more readable and supported in the
standard CString:

CString str;
str = CString(MAKEINTRESOURCE(IDC_MY_STRING));

-- David

.rhavin grobert

unread,
Feb 4, 2009, 1:09:12 PM2/4/09
to

guess you have...

class foo{
public:
inline void TestSet(LPCTSTR sz) {m_scTest = sz;};
private:
CString m_scTest;
};

Joseph M. Newcomer

unread,
Feb 4, 2009, 1:53:14 PM2/4/09
to
So who is 'they' and what is 'nuts' related to here? You seem to have extended CString
assignment by modifyting the CString source code in MFC, which actually seems a bit 'nuts'
to me. What's the question?

Note that this is already supported in the constructor.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Joseph M. Newcomer

unread,
Feb 4, 2009, 1:54:28 PM2/4/09
to
I'm curious why you think you have to support this in the assignment operator. Note you
could have put this code in your TestSet method without having to muck with the CString
definition.
joe

David Ching

unread,
Feb 4, 2009, 2:31:48 PM2/4/09
to
".rhavin grobert" <cl...@yahoo.de> wrote in message
news:fe6e6086-0df6-4c98...@e1g2000pra.googlegroups.com...

> guess you have...
>
> class foo{
> public:
> inline void TestSet(LPCTSTR sz) {m_scTest = sz;};
> private:
> CString m_scTest;
> };


I would say TestSet is buggy. Prototyping it to take an LPCTSTR and
expecting it to work with a resource ID is not something as a user of your
class I would expect. It doesn't expose any MFC stuff, and it's only
CString that can take a resource ID in place of an LPCTSTR in some cases
(the ctor). Why don't you add another method:

inline void TestSet(UINT resId) { m_scTest =
CString(MAKEINTRESOURCE(resId); }


-- David

.rhavin grobert

unread,
Feb 4, 2009, 2:36:34 PM2/4/09
to
On 4 Feb., 19:54, Joseph M. Newcomer <newco...@flounder.com> wrote:
> On Wed, 4 Feb 2009 10:09:12 -0800 (PST), ".rhavin grobert" <cl...@yahoo.de> wrote:
> >guess you have...
>
> >class foo{
> >public:
> >  inline void TestSet(LPCTSTR sz) {m_scTest = sz;};
> >private:
> >  CString m_scTest;
> >};

> I'm curious why you think you have to support this in the assignment operator. Note you


> could have put this code in your TestSet method without having to muck with the CString
> definition.
> joe
>
>

shure, but i have *a real lot* of those "TestSet"-methods in my
code...


> So who is 'they' and what is 'nuts' related to here? You seem to have extended CString
> assignment by modifyting the CString source code in MFC, which actually seems a bit
> 'nuts' to me.

of course not! i just noticed something missing in there.

> What's the question?

given the fact that CString is a really small piece of code ... how
could someone support
IntResources in the ctor and not in the op= !?

AliR (VC++ MVP)

unread,
Feb 4, 2009, 3:34:53 PM2/4/09
to
"David Ching" <d...@remove-this.dcsoft.com> wrote in message
news:9D047ECE-BCCF-4658...@microsoft.com...

Well said.

AliR.

Joseph M. Newcomer

unread,
Feb 4, 2009, 9:13:37 PM2/4/09
to
Try writing a definition

#define ResStr(x) CString(((UINT_PTR)(x)) <= 0xFFFF ? MAKEINTRESOURCE(x) : (x))

or

__inline CString MakeStr(UINT x) { return CString(MAKEINTRESOURCE(x)); }
__inline CString MakeStr(LPCTSTR s) {
return ((UINT_PTR)s) < 0xFFFF ? CString(MAKEINTRESOURCE((UINT) s)) : s; }

and the problem goes away.
joe

Mihai N.

unread,
Feb 5, 2009, 3:39:37 AM2/5/09
to
> class foo{
> public:
> inline void TestSet(LPCTSTR sz) {m_scTest = sz;};
> private:
> CString m_scTest;
> };


class foo{
public:
inline void TestSet(LPCTSTR sz) : m_scTest(sz) {};
private:
CString m_scTest;
};

It is better to initialize everything you can outside
the body of the constructor anyway.


--
Mihai Nita [Microsoft MVP, Visual C++]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email

Giovanni Dicanio

unread,
Feb 5, 2009, 5:06:17 AM2/5/09
to

"Mihai N." <nmihai_y...@yahoo.com> ha scritto nel messaggio
news:Xns9BA96B3...@207.46.248.16...

> class foo{
> public:
> inline void TestSet(LPCTSTR sz) : m_scTest(sz) {};
> private:
> CString m_scTest;
> };
>
> It is better to initialize everything you can outside
> the body of the constructor anyway.

TestSet is not a constructor... it is just a setter...
Or am I missing something here?

Thanks,
Giovanni


Jonathan Wood

unread,
Feb 5, 2009, 11:25:27 AM2/5/09
to
".rhavin grobert" <cl...@yahoo.de> wrote in message
news:f9d08d5e-7a41-4cb7...@y1g2000pra.googlegroups.com...

> of course not! i just noticed something missing in there.

It's not missing. It's implemented in the LoadString() method.

> given the fact that CString is a really small piece of code ... how
> could someone support
> IntResources in the ctor and not in the op= !?

There's nothing small about CString anymore. This functionality is
there--it's just not implemented the way you appear to think it should be.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com
http://www.softcircuits.com/blog/

.rhavin grobert

unread,
Feb 5, 2009, 2:57:10 PM2/5/09
to
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);
};

//-----------------------------------------------------------------------------
// the only real overload, we need to check for ResourceID
const CQString& CQString::operator=(LPCTSTR lpsz)
{


if (lpsz != NULL && HIWORD(lpsz) == NULL)
{
UINT nID = LOWORD((DWORD)lpsz);
if (!LoadString(nID))
TRACE1("Warning: implicit LoadString(%u) failed\n", nID);
return *this;
}

AliR (VC++ MVP)

unread,
Feb 5, 2009, 3:07:56 PM2/5/09
to
Why didn't you just make your operator overload take a UINT?

> // the only real overload, we need to check for ResourceID

> const CQString& operator=(UINT ResourceID);

That way you have yours that takes a resource ID, and CString has his own
that takes a LPCTSTR.

And also you won't have to cast your resource ID into a LPCTSTR when you
want to use the assignment operator.

Ali


".rhavin grobert" <cl...@yahoo.de> wrote in message

news:741e8083-bb60-485d...@s9g2000prg.googlegroups.com...

.rhavin grobert

unread,
Feb 5, 2009, 3:15:16 PM2/5/09
to
On 5 Feb., 21:07, "AliR \(VC++ MVP\)" <A...@online.nospam> wrote:
> ".rhavin grobert" <cl...@yahoo.de> wrote in message
> > // the only real overload, we need to check for ResourceID
> > const CQString& operator=(UINT ResourceID);

> Why didn't you just make your operator overload take a UINT?
>
> That way you have yours that takes a resource ID, and CString has his own
> that takes a LPCTSTR.
>
> And also you won't have to cast your resource ID into a LPCTSTR when you
> want to use the assignment operator.

It just to be consistent with the constructors.

>
> Ali
>
>

Its a point! i just added ....

inline const CQString& operator=(UINT nRscID)
{LoadString(nRscID); return *this;};

Doug Harrison [MVP]

unread,
Feb 5, 2009, 6:47:54 PM2/5/09
to
On Thu, 5 Feb 2009 11:57:10 -0800 (PST), ".rhavin grobert" <cl...@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

Mihai N.

unread,
Feb 6, 2009, 2:10:03 AM2/6/09
to
> TestSet is not a constructor... it is just a setter...
> Or am I missing something here?

Sorry, my bad. I missed something :-)
Somehow I did not pay attention to the name of the class.

Giovanni Dicanio

unread,
Feb 6, 2009, 3:12:23 AM2/6/09
to

"Mihai N." <nmihai_y...@yahoo.com> ha scritto nel messaggio
news:Xns9BA9EBA8...@207.46.248.16...

>> TestSet is not a constructor... it is just a setter...
>> Or am I missing something here?
>
> Sorry, my bad. I missed something :-)
> Somehow I did not pay attention to the name of the class.

No problem! :)

C++ is a complex language and evolving too, so I thought that might be a new
C++0x feature or something from Alexandrescu's advanced book on C++.

Giovanni


Mihai N.

unread,
Feb 7, 2009, 3:24:42 AM2/7/09
to
> I thought that might be a new
> C++0x feature or something from Alexandrescu's advanced book on C++.

Now you are making fun of me :-)
Well deserved though.

Giovanni Dicanio

unread,
Feb 7, 2009, 3:51:44 AM2/7/09
to

"Mihai N." <nmihai_y...@yahoo.com> ha scritto nel messaggio
news:Xns9BAB42E...@207.46.248.16...

>> I thought that might be a new
>> C++0x feature or something from Alexandrescu's advanced book on C++.
>
> Now you are making fun of me :-)
> Well deserved though.

No.
I don't make fun of anybody.

Giovanni

0 new messages