请问关于LPCWSTR的一个奇怪有关问题
请教关于LPCWSTR的一个奇怪问题
碰到一个奇怪的问题,百思不得其解,向高手请教。
以下m_str开头的变量都是跟编辑框关联的CString类型变量,以下两句代码是希望把几个字符串拼接起来,单独执行结果都是对的,但放在一起的话,得到的两个字符串却是相同的(地址一样),这是为什么呢?请高手指教。
另外,
这两句代码放在一起执行,结果是对的,两个字符串的地址也是不一样的,为什么前面就不行呢?
------解决方案--------------------
看来楼主根本不知道LPCWSTR这个名字里面的每个字母都代表着什么意思
首先,微软的typedef里面,以LP开头的都是指针,它们指向某一段内存空间,但这段内存空间是否可用理所当然不归它们管
LPCWSTR,就是被typedef的const wchar_t *
然后,CString对象调用operater+,实际上是调用了操作符重载成员函数,该成员函数返回一个CString对象,而CString对象可以隐式转换为一个LPCTSTR指针,指向它保存字符串数据的内存空间
知道了以上两点,就不觉得这个问题有什么奇怪的了
CString连加得到的是一个临时的CString对象,然后楼主直接将它转化为指针并保存下来——然后这个临时对象就析构了,这个指针指向的也是无效数据了
然后楼主又进行了一次这个过程——两次指针相同是巧合,两次指针都无效是必然
至于楼主的第二个问题,实际上又是一个基本常识
指针可以指向一段“直接写在源代码里的字符串文本”,那么这段字符串保存在哪里?指针只有4字节,它们不在乎自己指向的内存是否可用,那么谁管理“直接写在源代码里的字符串”?
答案是,所有直接写在源代码里的字符串文本,编译器都会在编译时把它们放在常量数据区(不同文件结构不同操作系统,具体实现不同),然后将代码中的字符串文本替换为指向常量数据区中字符串数据的指针
因为楼主不知道自己写对的代码为什么对,所以楼主也不知道自己写错的代码为什么错
建议从头复习基础知识
------解决方案--------------------
C++语言标准没有规定的东西,跟编译器实现相关的东西,就叫“巧合”
不管出现多少次,巧合就是巧合,这个版本的VS可能反复出现,下个版本的VS就完全不出现,这个编译器反复出现,另一个编译器就从不出现,就是这一类东西
甭管你是4句放到一起还是4万句放到一起,我就问一句,“C++标准有没有规定过这种情况?MFC实现有没有规定过这种情况?”
没有,那就是巧合。如果你非要追究里面的必然原因——编程的每一个结果都有其必然原因,“万象皆为因果”嘛——那请你明白,你要追究的,既不是C++也不是MFC,只是VS某版本编译器的实现。
正确的写法?
首先,CString是跟UNICODE宏相关的,所以使用LPCTSTR,而不是UNICODE版本的LPCWSTR
然后,自己定义一个CString对象用来保存连加的结果
最重要的是,使用指针的时候,必须清楚这个指针指向哪块内存,该内存由谁创建由谁删除!不清楚,就别用指针!不用指针就完成不了功能的时候,就强迫自己先弄清楚!
------解决方案--------------------
CStringW ip;
ip.Format(L"%s.%s.%s.%s",ip1,ip2,ip3,ip4);
LPCWSTR ptr_ip = ip.LPCWSTR():
碰到一个奇怪的问题,百思不得其解,向高手请教。
以下m_str开头的变量都是跟编辑框关联的CString类型变量,以下两句代码是希望把几个字符串拼接起来,单独执行结果都是对的,但放在一起的话,得到的两个字符串却是相同的(地址一样),这是为什么呢?请高手指教。
LPCWSTR IPAddress = m_strIP1 + _T(".") + m_strIP2 + _T(".") + m_strIP3 + _T(".") + m_strIP4;
LPCWSTR IPMask = m_strMask1 + _T(".") + m_strMask2 + _T(".") + m_strMask3 + _T(".") + m_strMask4;
另外,
LPCWSTR IPAddress = _T("123");
LPCWSTR IPMask = _T("456");
这两句代码放在一起执行,结果是对的,两个字符串的地址也是不一样的,为什么前面就不行呢?
LPCWSTR
CString
------解决方案--------------------
看来楼主根本不知道LPCWSTR这个名字里面的每个字母都代表着什么意思
首先,微软的typedef里面,以LP开头的都是指针,它们指向某一段内存空间,但这段内存空间是否可用理所当然不归它们管
LPCWSTR,就是被typedef的const wchar_t *
然后,CString对象调用operater+,实际上是调用了操作符重载成员函数,该成员函数返回一个CString对象,而CString对象可以隐式转换为一个LPCTSTR指针,指向它保存字符串数据的内存空间
知道了以上两点,就不觉得这个问题有什么奇怪的了
CString连加得到的是一个临时的CString对象,然后楼主直接将它转化为指针并保存下来——然后这个临时对象就析构了,这个指针指向的也是无效数据了
然后楼主又进行了一次这个过程——两次指针相同是巧合,两次指针都无效是必然
至于楼主的第二个问题,实际上又是一个基本常识
指针可以指向一段“直接写在源代码里的字符串文本”,那么这段字符串保存在哪里?指针只有4字节,它们不在乎自己指向的内存是否可用,那么谁管理“直接写在源代码里的字符串”?
答案是,所有直接写在源代码里的字符串文本,编译器都会在编译时把它们放在常量数据区(不同文件结构不同操作系统,具体实现不同),然后将代码中的字符串文本替换为指向常量数据区中字符串数据的指针
因为楼主不知道自己写对的代码为什么对,所以楼主也不知道自己写错的代码为什么错
建议从头复习基础知识
------解决方案--------------------
C++语言标准没有规定的东西,跟编译器实现相关的东西,就叫“巧合”
不管出现多少次,巧合就是巧合,这个版本的VS可能反复出现,下个版本的VS就完全不出现,这个编译器反复出现,另一个编译器就从不出现,就是这一类东西
甭管你是4句放到一起还是4万句放到一起,我就问一句,“C++标准有没有规定过这种情况?MFC实现有没有规定过这种情况?”
没有,那就是巧合。如果你非要追究里面的必然原因——编程的每一个结果都有其必然原因,“万象皆为因果”嘛——那请你明白,你要追究的,既不是C++也不是MFC,只是VS某版本编译器的实现。
正确的写法?
首先,CString是跟UNICODE宏相关的,所以使用LPCTSTR,而不是UNICODE版本的LPCWSTR
然后,自己定义一个CString对象用来保存连加的结果
最重要的是,使用指针的时候,必须清楚这个指针指向哪块内存,该内存由谁创建由谁删除!不清楚,就别用指针!不用指针就完成不了功能的时候,就强迫自己先弄清楚!
------解决方案--------------------
CStringW ip;
ip.Format(L"%s.%s.%s.%s",ip1,ip2,ip3,ip4);
LPCWSTR ptr_ip = ip.LPCWSTR():