Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Overloading type casting operators

Status
Not open for further replies.

timmay3141

Programmer
Dec 3, 2002
468
0
0
US
I was looking at the CString class, and I noticed the following member function

operator LPCTSTR() const;

I assumed this operator automatically casts a CString to a LPCTSTR if you send it to a function that needs a LPCTSTR. I'm writing a class that could use something like this, but my book didn't talk about how to make this kind of an operator. I created a similar declaration, and an implimentantion that would look like this:

CString::eek:perator LPCTSTR() const
{
return m_lpszBuffer;
}

This seemed to work correctly at first. However, it did not work when I was creating other operators. I had to create a specific operator for both the char* type and the actual class type. I also noticed that, under the globals folder in the classview, a function titled "$S1()" shows up. I actually created two of these operators, so an "$S2()" shows up as well. Am I doing something wrong?
 
>> However, it did not work

what does that mean? If you received a compile error you need to state so and post the error message.

Don't ever post "it did not work" that does not provide any meaningful information.

>> Am I doing something wrong?

Well in order to have any idea what you may have done wrong we would have to see what you did yes? post the relevant code.


-pete
 
you can also use mystring.c_str() to return a pointer to a char array if thats any use, but like pete said, try to give more detail in your error messages and we can help you more :)

K
 
Sorry I didn't clearify. I had this problem a few days ago, and I didn't remember exactly what wasn't working. I found a way around it, as I said, but I want to figure out why it isn't working.

Basically, I am creating a dynamically allocating string class that will have most of the member functions of CString but will add a few things. I'll just call the class CString here. The problem occurs when using the overloaded != operator. This is the code:

BOOL CString::eek:perator !=(LPCTSTR str)
{
return (strcmp(m_lpStr, str) != 0);
}

And this is the code that causes a compiler error:

strNewSymbol != m_strSymbol

with error

error C2666: '!=' : 2 overloads have similar conversions

If this is the only != operator overloaded, so I don't know what it's talking about. I thought that the LPCTSTR operator would convert it appropriately, then this operator would be used. When I create an operator specifically to handle another CString, it works fine:

BOOL CString::eek:perator !=(CString& str)
{
return (strcmp(m_lpStr, str.m_lpStr) != 0);
}

Actually, I just decided that the LPCTSTR has nothing to do with it. I guess I didn't test everything about this class when I created it, because != doesn't even work when the right hand side really is a LPCTSTR (I get the same error). The only thing I really need to know about LPCTSTR is why the "$S1" shows up in the ClassView under Globals, and why double clicking on the "operator LPCTSTR" under CString says that it cannot find the implimentation of the function. I would like to know why it's saying != is already overloaded, though. Could a != overloaded by default somehow if an == is overloaded as well?
 
Conversion operators often cause problems like that arising from the rules C++ uses to find a "best match. Conversion operators make more "paths" from one type to another to create a match. These errors can be hard to find.

Prefer using conversion constructors where possible so a class can control what converts to it instead of the other way around. If that's not possible, requiring an explicit conversion by adding functions like c_str might be the best way to go.
 
Read Scott Meyers "More Effective C++"

Item #5 - "Be wary of user-defined conversion functions"

-pete
 
To give you a more concrete answer about what's actually causing the error:

You probably have some code that looks like

Code:
X x;
Y y;

x != y;

There's no "perfect match," like X::eek:perator!=( Y ) or operator!=( X, Y ), so it instead tries to find the next best through conversion. If there's a constructor for a class W that takes an X, but X has a conversion operator for type Z, then the compiler won't be able to decide which one works better.

Or one of the few hundred other combinations of ambiguity you can introduce by using conversion operators (and even without using them, admittedly).


Also, as a matter of style, it's usually preferred to implement operator!= as a non-member. No big deal, just letting you know.
 
Oof.

In my example, I left out the fact that there exist operator!=( W, Y ) and operator!=( Z, Y ).
 
OK, thanks for your help everyone. The only thing I still don't understand is why the ClassView is having trouble with the LPCTSTR operator. The operator behaves correctly, but it's still showing up as a global with a name of $S1 for some reason.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top