string - 管理 CStringArray 条目

标签 string mfc

这是在 Visual Studio MFC 应用程序的上下文中。

CStringArray::Add()成员(member)需要 LPCTSTR争论。如果我使用 CString参数,我认为该参数被隐式转换为 LPCTSTR对于 Add()通过LPCTSTR CString 的运算符,所以如果我有 CStringArray arr和一个 CString s并调用arr.Add(s) ,这与调用 arr.Add((LPCTSTR)s) 完全相同,对吗?

所以当 Add()被调用,CStringArray只是存储传递的指针,还是制作字符串的单独副本并存储它?我这样问是因为我想知道添加字符串时是否必须创建一个持久字符串,或者添加字符串后是否可以将其删除。例如,如果 foo1() 中的任何一个, foo2() ,或foo3()下列说法正确的是?

class MyClass :
{
    ...
    CStringArray arr;
    CString mystr;
    void foo1() { arr.Add(_T("Bippety")); }
    void foo2() { CString s(_T("Boppety"); arr.Add(s); }
    void foo3() { mystr = _T("Boop"); arr.Add(mystr); }
    ...
};

让我担心的是foo1()之后和foo2()返回时,传递的参数超出范围并被删除。那么该数组是否拥有自己的副本,或者是否拥有无效的指针?

数据是否存储在CStringArray中只是一个指针,或者它实际上甚至创建了一个 CStringAdd()被称为?

最后,如果我通过了 LPCTSTR添加,那么我假设如果我通过调用 new 创建字符串添加它,那么我肯定要对 delete 负责在 CStringArray 之前查看它被毁了,对吧?

我只是不太明白 LPCTSTR 是如何做到的能够生存在CStringArray当它只是一个本地字符串时。

最佳答案

CStringArray 是存储 CString 的 MFC 类型数组。如果使用 Unicode 进行编译,则 CStringCStringW;如果使用 MBCS 进行编译,则 CStringCStringA >.

该类(class)的重点是您不必太担心内存管理。它为你做这件事。当您将 LPCTSTR 类型字符串传递给数组时,它会构造一个 CString 对象并将其添加到数组中。当 CStringArray 对象超出范围和/或其析构函数被调用时,它所持有的所有 CString 都将被清除。

但是,有一个警告......

CString 类或多或少都有引用计数。它有一个内部类,因此当您复制一个类时,它不会复制所有数据。相反,它添加了对某些内部结构的引用并使用它。如果您执行某些更改数据的操作,那么它会将自身与引用分离并设置自己的新数据结构。您必须单步执行代码才能看到这一点。

现在,CStringArray 有两个 Add() 方法。一个采用 LPCTSTR,另一个采用 const CString&。第二个创建 CString 的副本,执行上一段中提到的准引用计数。

这只是添加的信息。使用CStringArray,您确实不需要太担心内存管理。它会为您完成繁重的工作。

唯一需要担心 CString 引用计数的部分是,如果您做了愚蠢的事情并忽略了 const。

考虑以下代码:

#include <afx.h>
#include <stdio.h>

void main()
{

CString s("HERE is my string\n");
CStringArray sArray;
sArray.Add(s);
sArray.Add(s);

_tprintf((LPCTSTR) s);  // "HERE is my string"
_tprintf((LPCTSTR) sArray[0]); // "HERE is my string"
_tprintf((LPCTSTR) sArray[1]); // "HERE is my string"

sArray[0].MakeLower();

_tprintf((LPCTSTR) s);  // "HERE is my string"
_tprintf((LPCTSTR) sArray[0]); // "here is my string"
_tprintf((LPCTSTR) sArray[1]); // "HERE is my string"

LPCTSTR lpsz = sArray[1];
_tcsupr((LPTSTR) lpsz); // don't do it!!!, also changes s!!!


_tprintf((LPCTSTR) s);  // "HERE IS MY STRING"
_tprintf((LPCTSTR) sArray[0]); // "here is my string"
_tprintf((LPCTSTR) sArray[1]); // "HERE IS MY STRING"

}

如果您查看第三组的打印输出,您会发现当我们将 lpsz 转换为非常量字符串以调用 _tcsupr (strupr)。由于 MFC 对字符串进行引用计数的方式,“s”字符串内容也会受到影响。在第二个分组调用 CStringMakeLower() 成员函数的情况下,只有该特定字符串受到影响。

这比你要求的还要多。也许这会对人们有所帮助。

关于string - 管理 CStringArray 条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64013353/

相关文章:

python - 删除空格并使 python 字符串中的所有小写

c++ - MFC EditControl 的值不在私有(private)成员中

visual-studio - FindFirstFile 导致 "There is no disc in the drive"错误

c++ - 无法从 MFC DLL 创建模式对话框

c++ - CStatic 子类化控件无法接收输入消息

c - 如何删除与说明相同行的注释?

javascript - 如何获取字符串中最后一个字母字符?

android - Spanned 字符串的 getSpans 返回 Spanned 乱序?

string - 获取字符串向量元素之间的最小共享部分

c# - COleDispatchDriver 错误 : automation return value coercion failed, DISP_E_TYPEMISMATCH ($80020005)