管理 CStringArray 条目

Managing CStringArray entries

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

CStringArray::Add() 成员接受了一个 LPCTSTR 参数。如果我使用 CString 参数,我假设该参数被 CStringLPCTSTR 运算符隐式转换为 LPCTSTR for Add(),所以如果我有一个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() return 之后,传递的参数超出范围并被删除。该数组是保存自己的副本,还是保存无效指针?

数据存储在 CStringArray 中只是一个指针,还是它实际上什至在调用 Add() 时创建了一个 CString

最后,如果我将 LPCTSTR 传递给添加,那么我假设如果我通过调用 new 来添加它来创建字符串,那么我肯定负责 deleteCStringArray 被销毁之前对它进行处理,对吗?

我只是不太明白 LPCTSTR 是如何在 CStringArray 中生存的,因为它只是一个本地字符串。

CStringArray是一个MFC类型的数组,存放的是CString的。如果使用 Unicode 编译,CStringCStringW,如果使用 MBCS 编译,CStringCStringA.

class 的要点是您不必为内存管理操心。它为你做。当您将 LPCTSTR 类型的字符串传递给数组时,它会构造一个 CString 对象并将其添加到数组中。当 CStringArray 对象超出范围时 and/or 它的析构函数被调用,它持有的所有 CString 都将被清理。

但是,有一个警告...

CStringclass或多或少是引用计数。它有一个内部 class,因此当您复制 class 时,它不会复制所有数据。相反,它添加对某些内部结构的引用并使用它。如果你做了一些改变数据的操作,那么它就会从引用中分离出来并建立自己的新数据结构。您必须逐步执行代码才能看到这一点。

现在,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 转换为 non-const 字符串以调用 _tcsupr 时,我们违反了 const-ness(strupr).由于 MFC 引用计数字符串的方式,“s”字符串内容也受到影响。在第二个分组调用 CStringMakeLower() 成员函数的情况下,只有那个特定的字符串受到影响。

这比你问的要多。也许对大家有帮助。