 |
|
 |
There is a memory leak in "Format" method.
You should call
delete [] m_sString;
before:
m_sString = new TCHAR[m_iLength + 1];
Also calculating string lenght is not well written.
I suggest to change "Format" method to this:
-----------------------------------------------
void KString::Format(LPCTSTR pszCharSet, ...)
{
if(m_sString!=NULL) delete [] m_sString;
va_list vl;
va_start(vl, pszCharSet);
m_iLength = FormatLength(pszCharSet, vl);
m_sString = new TCHAR[m_iLength + 1];
m_sString[m_iLength] = 0;
_vsntprintf(m_sString, m_iLength, pszCharSet, vl);
va_end(vl);
}
int KString::FormatLength(LPCTSTR pszCharSet, va_list vl)
{
int nReturn = -1;
#if _MSC_VER < 1300
// < MSVCRT version 7.0
FILE *fp = _tfopen(_T("NUL"), _T("wb"));
if(fp)
{
nReturn = _vftprintf(fp, pszCharSet, vl);
fclose(fp);
}
#else
// >= MSVCRT version 7.0
nReturn = _vsctprintf(pszCharSet, vl);
#endif
return nReturn;
}
-----------------------------------------------
Regards,
TomazZ
|
|
|
|
 |
|
 |
Hi
Thank you again,
_vsctprintf is a good function and I did not know about it.
These years I'm just working on a math program and UI codes and I did not get a chance to update this article.
But thank you for your tips.
Regrads,
Hadi
www.logicsims.ir
|
|
|
|
 |
|
 |
Istead of this:
-----------------------------------
KString KString::Mid(int iStart)
{
if(iStart > m_iLength)
return _T("");
KString sTemp;
sTemp.m_iLength = m_iLength - iStart;
sTemp.m_sString = new TCHAR[sTemp.m_iLength + 1];
for(int i=0; i<sTemp.m_iLength; i++)
sTemp.m_sString[i] = m_sString[iStart + i];
sTemp.m_sString[i] = '\0';
return sTemp;
}
-----------------------------------
You can optimize to this:
-----------------------------------
KString KString::Mid(int iStart)
{
if(iStart > m_iLength)
return _T("");
return (LPCTSTR)(m_sString+iStart);
}
-----------------------------------
It is also a gr8 tutorial on how to implement class operators.
Regards,
TomazZ
modified on Thursday, October 28, 2010 10:14 AM
|
|
|
|
 |
|
 |
Hi
Oh yes, nice code.
Thank you.
I will replace it in next version of the article,
(As you see article is for 4 years ago.)
Regard,
Hadi
www.logicsims.ir
|
|
|
|
 |
|
 |
Excellent work Mr. Hadi Dayvary. Thanks!
Raja.
|
|
|
|
 |
|
 |
Thank you
|
|
|
|
 |
|
 |
I am new to vc++. I have created a dialog box with slider control. How can i process the slider message and design the control?
Thanks in Advance!!!
Raja
|
|
|
|
 |
|
 |
You can get NM_RELEASEDCAPTURE notification message.
|
|
|
|
 |
|
|
 |
|
 |
Hi,
I am trying to change the brightness of PPC by modifying registry value through code.
KEY: HKEY_CURRENT_USER\ControlPanel\BackLight
DWORD: ACBrigthness = 5
It's working. But, I can see the change after restarted only (soft reset) . I want to see the effect without restart PPC. How can i do this?
Thanks in Advance!
K. Raja
|
|
|
|
 |
|
 |
Hi
Sorry I just have a little experience with Pocket PC, may be sending a specified message can help you, please look at MSDN.
Goodluck
|
|
|
|
 |
|
 |
Actually, in VC++ 2003 (ATL 7) and later, CString is a stand alone class and is not tied to MFC.
|
|
|
|
 |
|
 |
Hello,
nice class...
but i miss an Array... e.g. TCHAR[]
Sample:
KString txt[100];
GetDlgItemText(IDC_EDIT1, &txt[0], 100);
... brings error: " 'KString *__64' can't convert to 'LPTSTR'...
can you help me?
|
|
|
|
 |
|
 |
Thank you
You must use:
KString txt[100];
txt[0].GetBuffer(100);
GetDlgItemText(IDC_EDIT1, txt[0], 100);
Good luck.
|
|
|
|
 |
|
 |
Soryy to say that, but I think it is useless to write another string class. std::string or std:wstring is robust, well known, standard non-MFC string class.
|
|
|
|
 |
|
 |
I have tried that (as a replacement for CString) but the problem is that most of what std::string gives you deals with iterating over individual characters which is an operation that I rarely do. What I need to do most is to operate on substrings.
John
|
|
|
|
 |
|
 |
then simply create a series of new "algorithms" for the std::string.
|
|
|
|
 |
|
 |
I know std::string was designed to be lightweight (and extended with algorithms) but from a person who has used CString for over 10 years and has written 500K lines of MFC code using std::string alone is a major disappointment. This is why I use CStdString which is basically a std::string with all the functionality of CString.
http://www.codeproject.com/string/stdstring.asp[^]
John
|
|
|
|
 |
|
 |
In a Nut Shell: Just because an operation can be applied to your class doesn't mean that the operation should be part of your class.
The trouble with this string is that it has so much heavy functiionality built in. There are tons of "clever" little things, like a built in format function, ToInt, ToFloat, etc. that have no place in a string class.
String are supposed to be efficient ways of holding onto dynamically sized char arrays, and nothing more.
Formatting and Conversions should be part of a utility class, because these operations are valid for ANY string class, as well as const char*. All that "custom" logic you are coming up with is not going to work with std::string, CString, etc.
You've also made a very fat interface. Everytime one of your users "needs" a new feature, you're going to cause the whole world to re-compile, because you're constantly changing the interface to one of your most important classes. New users are going to be confused by all of the weird functions they've never heard of that are shoved right into their faces.
I am pretty sure all those fancy "features" use the stdlib.h to get their work done, and perhaps some other fancy functions of your own design (which can be using other library functions, etc etc.) By including them in the implemtation of your class, you are forcing everyone links with your class to link in those libraries! Even if someone only wants you to manage his memory, you're making him link in the world!
Read Large-Scale C++ Software Design by Lakos for more on why this sort of functional coupling is bad.
|
|
|
|
 |
|
 |
We needed a customized and non MFC String class, so I wrote KString class.
Can you tell use just what customizations you needed?
|
|
|
|
 |
|
 |
Why hold length attribute. Without this is pointer to this class direct pointer to string and in this way is useable as 'const char *' for example in sprintf(%s)... . Metkod GetBuffer with parametr is (for me) unconstructive. And in this class absent Sprint or Format, And more....
Example:
CStr MidEx(UINT from,UINT to) const
{
CStr s;
if(from>=to) return s;
if(to>GetLength()) to=GetLength();
Copy(s,to-from,from,0);
return s;
}
... or
void Format(cStr *format, ...)
{
va_list v;
va_start(v,format);
Char *tmp=NULL;
int size=0;
int rv=-1;
// huh
do
{
size+=100;
delete []tmp;
tmp=new Char[size];
rv=_vsnprintf(tmp,size,format,v);
} while (rv<0);
size_t len=strlen(tmp);
Alloc(len);
strcpy(Text,tmp);
delete [] tmp;
va_end(v);
}
Martin
|
|
|
|
 |
|
 |
You must read Sutter & Meyers before trying to do something like this.
bad signatures w\o const
some operators must be friend - you do it members
bad functions which u can't implement correctly. Do u ever see MakeLower in stl? Why?
Answer you can read in "Writing Secure Code" MSPress
obsolete ansi - where is the unicode? why do you think windows works in unicode only?
obsolete int - what about 64bit platforms?
and etc and etc
|
|
|
|
 |
|
 |
Stop crying !!!
There are always people who THINK they know it better, but that doesn't mean that we want to hear them think !
|
|
|
|
 |
|
 |
your answer is off topic.
|
|
|
|
 |
|
 |
Then, why not write a similar & much much better one?
Thanks
Benben
|
|
|
|
 |