VC6.0中有关输出运算符<<的重载问题(备忘)

本文介绍了一个C++中重载输出运算符的具体案例,包括如何定义复数类及其实现,并解释了在VC6.0环境下使用不同iostream头文件的影响。

这两天一直被C++中重载输出运算符的问题困扰,查阅多方资料无果。今天在MSDN论坛翻了很久,终于找到解答,此文仅用于备忘,以便日后查阅。以下为测试小程序:

 

 

 

起初,在Complex.h文件中,使用:

#include<iostream>

using namespace std;

结果编译时出现错误,提示<<不能访问Complex的私有成员。

 

后改正为#include<iostream.h>,编译通过,且运行正常。

 

分析:

vc60下的<iostream> 不支持友元<<的重载方式。所以在6.0下若想以友元方式重载<<(输出运算符)的话,应该包含头文件<iostream.h>而非<iostream>。

<think>我们正在使用VC6.0 MFC环境,需要从vector<CString>中删除指定的字符串。 根据引用[2]和[3],我们知道CString对象不能直接转换为非常量指针(除非使用GetBuffer,但需要注意使用规则)。但是在删除操作中,我们主要是比较字符串内容。 在MFC中,CString类重载了比较运算符,因此我们可以直接使用==来比较两个CString对象的内容。 因此,我们可以使用标准库的算法std::remove或std::remove_if结合vector的erase方法来实现删除。 但是注意:VC6.0对C++标准的支持可能有限,特别是标准库。在VC6.0中,我们可以使用std::vector,但是std::remove和std::remove_if也是可用的。 具体步骤: 1. 遍历vector,找到与指定字符串相等的元素,然后删除。但这样效率较低,且需要自己控制迭代器(因为删除元素会使迭代器失效)。 2. 使用“erase-remove”惯用法:这是STL中删除元素的标准做法。 由于我们要删除所有等于指定字符串的元素,所以使用std::remove。 示例代码: vector<CString> strVec; CString strToRemove = _T("要删除的字符串"); // 使用remove算法将不等于strToRemove的元素移到前面,等于的移到后面,返回一个迭代器指向第一个等于strToRemove的元素位置 // 然后使用erase删除从该位置到末尾的所有元素 strVec.erase(std::remove(strVec.begin(), strVec.end(), strToRemove), strVec.end()); 但是,在VC6.0中,上述代码可能会遇到问题,因为VC6.0的STL实现可能不太完善。如果遇到问题,我们可以自己写循环删除。 另一种方法是使用循环,但要注意迭代器的失效问题。我们可以使用以下方式: for (vector<CString>::iterator it = strVec.begin(); it != strVec.end(); ) { if (*it == strToRemove) { it = strVec.erase(it); // erase返回下一个元素的迭代器 } else { ++it; } } 这种方法在VC6.0中应该是可行的。 注意:在比较CString时,我们使用的是==运算符,它会进行内容比较(而不是指针比较),因为CString重载了==。 根据引用[4],CString使用了写入复制技术,但在这里我们只是读取比较,所以不会触发复制,效率没有问题。 因此,我们有至少两种方法: 方法一(推荐,如果STL支持良好): strVec.erase(std::remove(strVec.begin(), strVec.end(), strToRemove), strVec.end()); 方法二(循环删除): for (vector<CString>::iterator it = strVec.begin(); it != strVec.end(); ) { if (*it == strToRemove) { it = strVec.erase(it); } else { it++; } } 考虑到VC6.0对STL的支持可能不太好,方法二更稳妥。 另外,如果我们需要删除满足特定条件的元素(不仅仅是相等),可以使用std::remove_if,但同样要考虑STL支持。 所以,在VC6.0环境下,我们可以选择使用循环删除的方法。 示例代码: #include <vector> using namespace std; vector<CString> vec; // ... 填充vec ... CString strTarget = _T("hello"); // 删除所有等于strTarget的字符串 for (vector<CString>::iterator i = vec.begin(); i != vec.end(); ) { if (i->Compare(strTarget) == 0) { // 或者使用 *i == strTarget i = vec.erase(i); } else { i++; } } 这里使用了erase的返回值来更新迭代器,避免失效。 注意:在MFC中,也可以使用CStringArray,但问题要求是vector<CString>。 因此,我们提供了两种方法,并推荐在VC6.0中使用循环删除的方法。 </think>在 VC6.0 MFC 环境下,从 `vector<CString>` 中删除指定字符串可通过以下两种方法实现: --- ### **方法1:使用迭代器循环删除(推荐)** ```cpp #include <vector> #include <afx.h> // MFC 核心头文件 void RemoveStringFromVector(std::vector<CString>& vec, const CString& target) { for (auto it = vec.begin(); it != vec.end(); ) { // 直接比较 CString 内容(运算符重载支持) if (*it == target) { it = vec.erase(it); // erase() 返回下一个有效迭代器 } else { ++it; // 未删除时迭代器自增 } } } ``` **说明:** 1. **直接比较内容**:`CString` 已重载 `==` 运算符,可直接比对字符串内容[^2]。 2. **安全删除**:`erase()` 返回删除后的下一个有效迭代器,避免迭代器失效问题。 3. **适用场景**:适用于所有符合 ANSI/Unicode 编码的 `CString` 对象。 --- ### **方法2:使用 STL 的 `std::remove` 算法** ```cpp #include <algorithm> #include <vector> #include <afx.h> void RemoveStringFromVector(std::vector<CString>& vec, const CString& target) { // 移除非目标元素到容器前端,返回新逻辑结尾 auto newEnd = std::remove(vec.begin(), vec.end(), target); vec.erase(newEnd, vec.end()); // 删除尾部无效元素 } ``` **注意事项:** - VC6.0 的 STL 实现可能存在兼容性问题,若编译失败建议改用**方法1**。 - `std::remove` 仅移动元素,需配合 `erase()` 完成实际删除[^4]。 --- ### **关键原理** 1. **`CString` 内容比对**: 无需转换为 `char*`,直接使用 `==` 或 `CString::Compare()` 即可安全比较内容[^2][^4]。 2. **写入复制优化**: `CString` 的 Copy-On-Write 机制确保高效复制,删除操作不会引发额外内存开销[^4]。 3. **迭代器安全**: 循环删除时需通过 `erase()` 返回值更新迭代器,防止因元素移动导致的失效问题[^3]。 --- ### **使用示例** ```cpp std::vector<CString> data; data.push_back(_T("Apple")); data.push_back(_T("Banana")); data.push_back(_T("Apple")); // 删除所有 "Apple" RemoveStringFromVector(data, _T("Apple")); // 结果:data = {"Banana"} ``` --- ### **相关问题** 1. 如何在 `vector<CString>` 中高效查找特定字符串? 2. `CString` 的 Copy-On-Write 机制如何影响容器操作性能? 3. VC6.0 中处理 `std::vector` 与 MFC 容器类(如 `CStringArray`)有何优劣? [引用说明] [^2]: CString 支持直接内容比较,无需转换指针。 [^3]: 容器删除需正确处理迭代器失效问题。 [^4]: CString 的写入复制机制优化内存使用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值