【问题标题】:CStringArray::GetAt(int index) returns a const. Why?CStringArray::GetAt(int index) 返回一个常量。为什么?
【发布时间】:2017-08-25 10:15:10
【问题描述】:

我有一个CStringArray,我想打电话给CString::MakeUpper(),你知道,把它改成大写。

我正在尝试这样:

mycstringarray.GetAt(0).MakeUpper();

mycstringarray 是这样声明的:

CStringArray mycstringarray;
mycstringarray.SetSize(46);
mycstringarray.setAt(0,CString("StayClassySandiego"))

但 Visual Studio 抱怨它无法将 this 指针从 const CString 转换为 &

我知道不能在 const 上执行非 const 函数,但为什么 GetAt() 返回一个 const?更重要的是,如果 const 的返回确实是设计的,而不是乱七八糟的,我该如何执行此操作?

【问题讨论】:

  • 但为什么 GetAt() 返回一个 const? 因为有人决定这样做。
  • 查看GetAt 的文档,我可以看到它返回TCHAR,即wchar_tchar。你如何设法从它调用一个带有点的函数?
  • GetAt 在定义的位置返回字符的副本。因此,您不能使用 GetAt 修改字符串。这就是为什么它是常量。返回类型 TCHAR 可能是 char 或 wchar_t,这是一种普通类型,没有任何成员函数。您只能在完整的字符串上调用 MakeUpper()。
  • 我编辑显示定义

标签: c++ arrays string visual-studio mfc


【解决方案1】:

那是因为CStringArray(或更准确地说是CObArray)的接口是如何定义的。它返回对底层元素的const 引用。而MakeUpper 只能在非const 对象上调用,因为它直接操作该对象。

如果要更改索引位置的值,请​​使用[] 运算符或ElementAt() 方法。

【讨论】:

  • 啊,是不是GetAt()只适合查看数据,而不是修改它调用GetData()?
  • @user3064874 如他所说,或[]mycstringarray[0].MakeUpper();
  • 很好。这确实解决了我的问题并改变了我的方法。
  • 我相信使用ElementAt 是一种更好的方法。 GetData 是较低级别的,它返回一个指向底层原始数组的指针(视图)。
  • @SebastianStern:我注意到您在我发表评论后更改了答案,删除了 GetData 并建议使用指向 ElementAt MSDN 文档的链接的“GetElement”。此时,您可能想要修复您的答案,将“GetElement”替换为ElementAt :)
【解决方案2】:

根据MSDN doc for CStringArray::GetAt,这个方法的原型是:

CString GetAt( INT_PTR nIndex ) const;

另一方面,我在 <afxcoll.h> 内部进行了探索,并且(至少在 VS2015 中)它包含以下声明:

const CString& GetAt(INT_PTR nIndex) const;

因此,MSDN 文档与 Visual Studio 随附的实际代码不匹配。当然,实际编译出来的是后者,所以我们重点讲一下。

CStringArray::GetAt 返回一个 const 引用 到原来的CString,由于const,你不能修改它。

但是,如果您确实想修改存储在数组中的元素,您可以使用 ElementAt 方法,声明如下:

CString& ElementAt(INT_PTR nIndex);

换句话说,这段代码应该可以工作:

yourStringArray.ElementAt(0).MakeUpper();

还有operator[] 的重载,它只是在其实现中调用ElementAt。所以yourStringArray[0].MakeUpper(); 也应该可以工作。


PS我想补充一点,在现代 C++ 代码中,您可能需要考虑 标准 容器类,例如 std::vector,而不是这些旧的 MFC容器。

请注意,std::vectorCString 类配合得很好,因此您可以考虑在代码中使用 vector<CString>

【讨论】:

  • 非常感谢您“探索”。我肯定会考虑摆脱旧的 MFC 容器。我正忙于迁移某人的 Visual Studio 1998 代码,所以这将被添加到待办事项列表中。
猜你喜欢
  • 2017-06-12
  • 2020-10-31
  • 1970-01-01
  • 2013-02-26
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多