class()的妙用

#pragma warning(disable:4786)
#include <iostream.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const string ToothbrushCode("0003");
class IsAToothbrush
{public:  
bool operator() ( string& SalesRecord )
{return SalesRecord.substr(0,4)==ToothbrushCode;}    
};
void main (void)
{
  vector<string> SalesRecords;
  SalesRecords.push_back("0001 Soap");
  SalesRecords.push_back("0002 Shampoo");
  SalesRecords.push_back("0003 Toothbrush");
  SalesRecords.push_back("0004 Toothpaste");
  SalesRecords.push_back("0003 Toothbrush"); 
int NumberOfToothbrushes(0);  
  NumberOfToothbrushes = count_if (SalesRecords.begin(), SalesRecords.end(),IsAToothbrush());
  cout << "There were " << NumberOfToothbrushes << " toothbrushes sold" << endl;
}  

结果:
There were 2 toothbrushes sold
__________________________________________________________________

#pragma warning(disable:4786)
#include <iostream.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class IsAToothbrush
{
public:
IsAToothbrush(string& InToothbrushCode) : ToothbrushCode(InToothbrushCode) {}
bool operator() (string& SalesRecord)
{ return SalesRecord.substr(0,4)==ToothbrushCode; }      
private:
string ToothbrushCode;        
};
void main (void)
{
vector<string> SalesRecords;
SalesRecords.push_back("0001 Soap");
SalesRecords.push_back("0002 Shampoo");
SalesRecords.push_back("0003 Toothbrush");
SalesRecords.push_back("0004 Toothpaste");
SalesRecords.push_back("0003 Toothbrush");
string VariableToothbrushCode("0003");
int NumberOfToothbrushes(0);  
NumberOfToothbrushes = count_if (SalesRecords.begin(), SalesRecords.end(),
IsAToothbrush(VariableToothbrushCode));
cout << "There were  " << NumberOfToothbrushes << " toothbrushes matching code "<< "0003" << " sold" << endl;
}

结果:
There were  2 toothbrushes matching code 0003 sold

内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
<think>我们正在讨论ES6Symbol的使用场景和高级用法。根据引用内容,我们可以总结出以下几点:1.**模拟私有属性和方法**(引用[1]和引用[3]):-在类中,由于没有private关键字,可以使用Symbol的唯一性来模拟私有成员。-示例:在类中定义一个Symbol作为键,这样外部无法直接访问(因为无法获得同一个Symbol引用),从而实现了私有性。2.**避免属性名冲突**(引用[1]和引用[3]):-当多个模块操作同一个对象时,使用Symbol作为属性键可以避免键名冲突。 3. **代替常量**(引用[3]):-使用Symbol代替常量,可以保证每个值都是唯一的,不需要为常量赋予具体的值(因为常量之间只需要互不相同,而不需要具体的值)。4.**定义元编程行为**(内置Symbol值):-引用[2]和引用[4]提到了`Symbol.for`和`Symbol.keyFor`,以及引用[3]提到了`Reflect.ownKeys`可以获取Symbol键。-此外,还有内置Symbol值(如`Symbol.iterator`、`Symbol.toStringTag`等)用于改变对象的默认行为(元编程)。 5. **全局共享Symbol**(引用[2]和引用[4]):-使用`Symbol.for(key)`可以在全局注册表中创建或获取一个Symbol,这样在不同的地方可以通过相同的key获取到同一个Symbol,实现共享。 6. **保密属性和方法**(引用[3]):-在模块中定义Symbol属性,然后导出对象,但外部无法获取到Symbol键(除非导出Symbol),因此无法访问这些属性,达到保密效果。 7. **元编程(修改语言内部行为)**:-通过定义对象的`Symbol.iterator`方法,可以使对象可迭代(用于`for...of`循环)。-通过`Symbol.toStringTag`自定义对象的`toString`行为。-通过`Symbol.species`指定创建派生对象时使用的构造函数。下面我将详细展开这些使用场景和高级用法。</think>### ES6 Symbol 使用场景与高级用法详解 #### 一、核心使用场景 1. **模拟私有属性** [^1][^3] 解决类中无 `private` 关键字的问题: ```javascript const _salary = Symbol('salary'); class Employee { constructor(name, baseSalary) { this.name = name; this[_salary] = baseSalary; // 私有属性 } getSalary() { return this[_salary]; // 仅内部可访问 } } const emp = new Employee('Alice', 10000); console.log(emp[_salary]); // 报错:_salary未定义(外部无法访问) ``` 2. **避免属性冲突** [^1][^3] 多模块协作时防止属性覆盖: ```javascript // 模块A.js const cacheKey = Symbol('cache'); export function setCache(obj, value) { obj[cacheKey] = value; } // 模块B.js const cacheKey = Symbol('cache'); export function getCache(obj) { return obj[cacheKey]; // 不会与模块A冲突 } ``` 3. **替代常量枚举** [^3] 创建真正唯一的标识符: ```javascript // 传统常量(值可能重复) const LOG_LEVEL = { DEBUG: 0, INFO: 1, ERROR: 2 }; // Symbol方案(绝对唯一) const LOG_LEVEL = { DEBUG: Symbol('debug'), INFO: Symbol('info'), ERROR: Symbol('error') }; console.log(LOG_LEVEL.DEBUG === LOG_LEVEL.INFO); // false ``` #### 二、高级用法 1. **元编程(Metaprogramming)** 通过内置 Symbol 改变对象核心行为: ```javascript // 自定义对象迭代行为 const customCollection = { data: [10, 20, 30], [Symbol.iterator]: function* () { for (let item of this.data) yield item * 2; } }; console.log([...customCollection]); // [20, 40, 60] [^1] // 自定义toString标签 class CustomClass { get [Symbol.toStringTag]() { return 'MyCustomClass'; } } console.log(new CustomClass().toString()); // [object MyCustomClass] ``` 2. **跨模块共享 Symbol** [^2][^4] 使用全局注册表实现 Symbol 复用: ```javascript // 模块A const GLOBAL_KEY = Symbol.for('APP_SECRET'); localStorage.setItem(GLOBAL_KEY, 'token123'); // 模块B const secretKey = Symbol.for('APP_SECRET'); console.log(localStorage.getItem(secretKey)); // 'token123' ``` 3. **安全属性存储** 结合 WeakMap 实现真正私有: ```javascript const privateData = new WeakMap(); const _internal = Symbol('internal'); class SecureData { constructor(secret) { privateData.set(this, { [_internal]: secret }); } reveal() { return privateData.get(this)[_internal]; } } const data = new SecureData('confidential'); console.log(data.reveal()); // 'confidential' console.log(data[_internal]); // undefined (外部不可访问) ``` #### 三、工程实践技巧 1. **属性枚举控制** Symbol 属性不会出现在常规遍历中: ```javascript const obj = { public: 'visible', [Symbol('private')]: 'hidden' }; for (let key in obj) console.log(key); // 只输出 'public' console.log(Reflect.ownKeys(obj)); // ['public', Symbol(private)] [^3] ``` 2. **类型安全转换** 避免隐式转换错误: ```javascript const sym = Symbol('desc'); // 安全转换方案 console.log(sym.toString()); // 'Symbol(desc)' console.log(String(sym)); // 'Symbol(desc)' // 危险操作(会报错) try { console.log(sym + ''); } catch (e) { console.error(e); // TypeError: Cannot convert a Symbol value to a string } ``` 3. **协议化扩展** 实现自定义对象协议: ```javascript // 自定义异步迭代协议 const asyncIterable = { [Symbol.asyncIterator]: async function* () { yield await fetch('/data/1'); yield await fetch('/data/2'); } }; for await (const res of asyncIterable) { console.log(await res.json()); } ``` #### 四、性能优化建议 1. **全局 Symbol 缓存** 高频使用的 Symbol 应全局注册: ```javascript // 避免重复创建 const Keys = { CACHE: Symbol.for('CacheKey'), AUTH: Symbol.for('AuthToken') }; ``` 2. **Symbol 与 Map 结合** 大量私有属性时更高效: ```javascript const privateStore = new Map(); class HighPerfClass { constructor(id) { privateStore.set(this, { id }); } get id() { return privateStore.get(this).id; } } ``` --- ### 相关问题 1. Symbol 属性如何通过 `Object.getOwnPropertySymbols()` 与 `Reflect.ownKeys()` 实现精确控制?[^3] 2. 使用 `Symbol.species` 自定义派生类构造函数的实际案例有哪些? 3. 在 TypeScript 中如何为 Symbol 属性添加类型声明? 4. 如何利用 `Symbol.hasInstance` 改变 `instanceof` 运算符的行为? 5. 浏览器不支持 Symbol 时,有哪些兼容方案能保持类似功能? > 参考资料: > [^1]: Symbol 作为私有属性键可防止外部直接访问,`Symbol.iterator` 实现自定义迭代协议。 > [^2]: `Symbol.for()` 在全局注册表中创建可复用的 Symbol,相同 key 返回相同值。 > [^3]: Symbol 属性需通过 `Reflect.ownKeys()` 获取,常规遍历方法不可见。 > [^4]: 全局注册的 Symbol 可通过 `Symbol.for()` 跨模块共享,实现安全数据传递。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值