2017-08-25 160 views
2

我有一个CStringArray,我想对它打电话CString::MakeUpper(),你知道的,大写。CStringArray :: GetAt(int index)返回一个常量。为什么?

我想这样的:

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的返回确实是由设计决定的并且不会被混淆,我该如何执行这个操作?

+1

_but为什么GetAt()返回一个const?_因为有人决定这样做。 – muXXmit2X

+0

查看[GetAt](https://msdn.microsoft.com/en-us/library/aa314338(v = vs.60).aspx)的文档,我可以看到它返回'TCHAR',它或者是' wchar_t'或'char'。你如何设法用点来调用一个函数? – teivaz

+0

GetAt返回定义位置处的字符副本。所以你不能通过使用GetAt来修改字符串。这就是为什么它是常量。返回类型TCHAR可能是一个char或wchar_t,它是一个平凡的类型,并没有任何成员函数。您只能在完整的字符串上调用MakeUpper()。 – lars

回答

3

那么,这是因为如何界定CStringArray(或更准确地说CObArray)的界面。它返回一个const对底层元素的引用。而MakeUpper只能在非const对象上调用,因为它直接对对象进行修改。

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

+0

啊,所以GetAt()只适合查看数据,而不是修改它调用GetData()吗? – user3064874

+1

@ user3064874就像他说的那样,或者像'mycstringarray [0] .MakeUpper();' – acraig5075

+0

那样的'[]'很好。这确实解决了我的问题并改变了我的方法。 – user3064874

1

按照MSDN doc for CStringArray::GetAt,该方法的原型为:

CString GetAt(INT_PTR nIndex) const; 

在另一方面,我spelunked内部<afxcoll.h>和(至少在VS2015)它包含此声明:

const CString& GetAt(INT_PTR nIndex) const; 

因此,MSDN文档和Visual Studio附带的实际代码之间存在不匹配。当然,实际编制的是后者,所以我们来关注这个。

CStringArray::GetAt返回常量引用原来的CString,你不能修改它因const

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

CString& ElementAt(INT_PTR nIndex); 

换句话说,这代码应工作:

yourStringArray.ElementAt(0).MakeUpper(); 

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


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

请注意,std::vector适用于CString类,因此您可以考虑在代码中使用vector<CString>

+0

你“spelunking”非常感谢。我一定会考虑离开我的旧MFC容器。我正忙于迁移某人的Visual Studio 1998代码,所以这将被添加到待办事项列表中。 – user3064874

相关问题