|
Hi,
This is a class which encapsulates a char * and which has an operator== defined which I think should work. But it does not. Can you tell why?
Please whatch below in code at '***' for further explanation
class IBZXMLLAYER_API String {<br />
public:<br />
explicit String():m_szValue(NULL) {};<br />
String(String & toCopy):m_szValue(new char[toCopy.length()]) {strcpy(m_szValue, (const char*)toCopy);}<br />
String(char const * const szValue):m_szValue(new char[strlen(szValue)+1]) {strcpy(m_szValue, szValue);};<br />
~String() {delete [] m_szValue;};<br />
size_t length() {return strlen(m_szValue);}<br />
operator const char*() const {return m_szValue?m_szValue:"";};<br />
String & operator=(std::string const & strToCopy);<br />
String & operator=(char const * const szToCopy);<br />
<br />
<br />
bool operator== (String const & toCompare) const {return 0 == strcmp( (const char*)this, (const char*)toCompare ); };<br />
<br />
bool operator> (String const & toCompare) const {return 0 > strcmp( (const char*)this, (const char*)toCompare ); };<br />
bool operator< (String const & toCompare) const {return 0 < strcmp( (const char*)this, (const char*)toCompare ); };<br />
private:<br />
char * m_szValue;<br />
};
Regards
Werner
|
|
|
|
|
You are performing an explicit cast via (const char*)this.
It is not resolving to operator const char*().
If you _really_ want to do it this way (i wouldn't) then use operator const char*().
e.g
bool operator == (String const & toCompare) const {
return 0 == strcmp( operator const char*(), (const char*)toCompare );
}
[EDIT]
this is a pointer, so when you try to cast with (const char*) the compiler assumes you know what you are doing and treats the pointer as a (const char*) as opposed to what it is (String*).
toCompare is an instance of a String, so when you try to cast with (const char*) the compiler also assumes you know what you are doing, but it also assumes you have told it how to convert a non-pointer object to a pointer (operator const char*()).
[/EDIT]
...cmk
Save the whales - collect the whole set
-- modified at 6:53 Thursday 27th October, 2005
|
|
|
|
|
You are right,
(const char*)this
does - of course - not resolve to
operator const char*() of *this.
If I had used
static_cast<const char*>(*this)
the compiler would have complained when trying to cast this to char*
static_cast<const char*>(this).
Regards
Werner
-- modified at 7:19 Thursday 27th October, 2005
|
|
|
|
|
> If you _really_ want to do it this way (i wouldn't) then use operator const char*()
Why not would you?
Thank you.
Regards
Werner
|
|
|
|
|
Generally whenever i see a cast i wonder what is going on.
That is, the code is not as clear as it could be.
I would be more inclined to do something like:
long String::Cmp( const String &S )
{
if( m_szValue == S.m_szValue ) return(0);
if( !m_szValue ) return(-1);
if( !S.m_szValue ) return( 1);
return( strcmp(m_szValue, S.m_szValue) );
}
bool String::operator == ( const String &S ) const { return( Cmp(S) == 0 ); }
bool String::operator < ( const String &S ) const { return( Cmp(S) < 0 ); }
...
My Cmp() actuall takes another parameter that defines how the compare is done, i.e. case-insensitive, numeric, ignore (leading, middle, trailing) spaces, ...
...cmk
Save the whales - collect the whole set
|
|
|
|
|
Dear Chris,
I argued with my colleague about this yesterday and thought about it in the evening as well.
I think, the problem actually is, that I wanted an extractor, but I overrode the cast operator instead. I did so because it has often been done in the Windows API (_variant_t, _bstr_t), rather than it had been much convenient to do so.
(1) I can see now, that this is much dangerous because it is syntactically equivalent to an old style cast.
(2) There is also a a point with _variant_t and _bstr_t - Extractors, which I don't like at all. They sound like (char * const) and this doesn't say at all, what it is actually doing. Syntactically they are like functions without a name. I will prefer something like std::string extractor c_str in the future.
(3) I rarely use true casts at all. I had some cases, where type conversions were necessary because I used results from one library as inputs for an other. But I didn't cast there, because this would hide the fact of conversion during compilation. So someone who compiled the program would not be warned and would not check, whether the cast is ok under the circumstances given.
Regards Werner
|
|
|
|
|
Hi,
I think you made an error in your constructors.
WernerPos wrote: String(String & toCopy):m_szValue(new char[toCopy.length()]) {strcpy(m_szValue, (const char*)toCopy);}
String(char const * const szValue):m_szValue(new char[strlen(szValue)+1]) {strcpy(m_szValue, szValue);};
you didn't forget to allocate space for the ending 0, but did forget to initialize it.
String(String & toCopy): m_szValue(new char[toCopy.length() + 1])
{
strcpy(m_szValue, (const char*)toCopy);
m_szValue[toCopy.length()] = 0;
}
String(char const * const szValue):m_szValue(new char[strlen(szValue)+1])
{
strcpy(m_szValue, szValue);
m_szValue[strlen(szValue)] = 0;
};
This causes to have a wrong result for
size_t length() {return strlen(m_szValue);}
because strlen gives the number of chars until the first '\0'.
bool operator== (String const & toCompare) const {return 0 == strcmp( (const char*)this, (const char*)toCompare ); };<br />
bool operator> (String const & toCompare) const {return 0 > strcmp( (const char*)this, (const char*)toCompare ); };<br />
bool operator< (String const & toCompare) const {return 0 < strcmp( (const<br />
char*)this, (const char*)toCompare ); };<br />
because strcmp alsoo requires the ending '\0' to compare the strings or which is greater or not.
Regards Kurt
codito ergo sum
|
|
|
|
|
: ->
before I get flamed or anything, my apologies
strcpy does alsoo copies the ending '\0'. (I've confused it with memcpy, or strncpy ).
But still, in the second constructor you need to add an additonal character to store the zero.
String(String & toCopy): m_szValue(new char[toCopy.length() + 1]) <br />
{ strcpy(m_szValue, (const char*)toCopy); }
My sincere apologies of someone who is of sleep deprived
codito ergo sum
|
|
|
|
|
That's true, thank you.
Regards Werner
|
|
|
|
|
Thanks, but this was not the problem actually..
"The strcpy function copies strSource, including the terminating null character".
It was the cast operator, and the use of casting at all.
|
|
|
|
|
I have several views reside in ChildFrm, when one of them already created, I want it to appears using SetActiveView(Specific View), but that doesn't work
-- modified at 5:18 Thursday 27th October, 2005
After calling the view's ShowWindow(SW_SHOW/SW_HIDE) in synchronized manner, I solved the problem. But I thought SetActiveView(...) will do it once for all, namely it would bring the specific view on the top of the others and automatic hides other views, but...
|
|
|
|
|
hey...
in my program i am assigning a value to a 'long' variable..on compilation it gives following warnings
1)truncation from Const_int64 to long
2)truncation of Const Value
...though the value is large(13 digit) but it is in the range of 'long' datatype (i.e. -9,223,372,036,854,775,808 to -9,223,372,036,854,775,807)...
what could possibly be wrong ?
thanks
|
|
|
|
|
That's perfectly normal: your compiler doesn't know what is the value contained in your Const_int64 variable ! So it just warns you that you are copying this value into a long that is shorter so a loss of data may occur.
To get rid of the warning, make an explicit cast:
Const_int64 Var1 = ....;<br />
long Var2 = (long)Var1;
In this case, you explicitly tell the compiler you know what you are doing
|
|
|
|
|
Isn't a long 32 bits in VC?
For VC6, sizeof(long) == 4
This gives (according to LIMITS.H):
ULONG_MAX 4294967295 (0xffffffff) Maximum unsigned long value
LONG_MAX 2147483647 Maximum (signed) long value
LONG_MIN –2147483647–1 Minimum (signed) long value
So IMO, a value with 13 digits should be truncated, big time...
You might considder to use the LONGLONG data type. That's a 64-bit signed integer.
|
|
|
|
|
Hi,
i want to use in vc++ 6.0 on windows Xp, xp like scrollbars, but i`m creating the scrollbar control in a dialog witch is in a dynamicaly linked dll...
NG
|
|
|
|
|
Neagoe Gabriel wrote: i want to use in vc++ 6.0 on windows Xp, xp like scrollbars
You can use
manifests[^] for that
|
|
|
|
|
I keep getting compiler errors from this file
wincrypt.h
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WinCrypt.h(249): error C2501: 'HCRYPTPROV' : missing storage-class or type specifiers
I've downloaded tutorials from this site..http://www.ultimategameprogramming.com/
The open gl tutorials for windows.
Normality is a weakness...
|
|
|
|
|
#define _WIN32_WINNT 0x0600
#define WINVER 0x0600
and u better use the latest sdk from ms - its free
|
|
|
|
|
Where do I put these declarations? I put them in wincrypt.h and in winbase.h. Still no luck...
Thanks for your help.
Normality is a weakness...
|
|
|
|
|
put them in your stdafx.h or in the source file where you include wincrypt.h you should not be modifying system headers! dingbat!
|
|
|
|
|
Well I tried that with a project having only one source file and no stdafx.h and it didn't work.
Normality is a weakness...
|
|
|
|
|
As a last measure, u can define it in your code:
<br />
typedef unsigned long ULONG_PTR;<br />
typedef ULONG_PTR HCRYPTPROV;<br />
|
|
|
|
|
Hi
I wrote this.
int SelectTest(char * strTest,...)
{
va_list marker;
char *temp = NULL;
va_start( marker, strTest );
temp = strTest;
while(temp)
{
//doing something with 'temp'
temp = NULL;
temp = va_arg( marker, char*);
}
va_end( marker );
...
}
if I call the function with 2 params like SelectTest("test1","test2");
va_arg is called 3 times rather than once.
and last two calls return garbage value (like "\?" )
And I know it would be better to call with Null parameter
(SelectTest("test1","test2",NULL);
Except this, any better idea?? thanks.
|
|
|
|
|
Well, u said it yourself, u better call with NULL in the end of arguments. Coz if u dont, how would your loop know where to end?
The thing is that va_arg doesn't see any 'end_of_args' marker simply because there isn't any end - its just stack and stack all the way down
|
|
|
|
|
plowstar wrote: Except this, any better idea??
Nope. Variable-argument lists must have a terminator.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|