重载++/--运算符

今天看书,看到例子里有个重载自增运算符,前自增还比较好。看后自增的时候有点迷惑。查 c++primer才发现自己这里有知识漏洞。特此补上。

 

在为类定义自增自减运算符的时候要注意,如何区分前自增/自减 和 后自增/自减运算符。

 

1 定义前自增/自减运算符

 

class CheckedPtr{

public:

     CheckedPtr& operator++();

     CheckedPtr& operator--();

 

};

 

 

 

CheckedPtr& CheckedPtr::operator++()

{

if(curr==end)

throw out_of_range("");

++curr;

return* this;

}

 

CheckedPtr& CheckedPtr::operator--()

{

if(curr==beg)

throw out_of_range("");

--curr;

return* this;

}

 

 

为了与内置类型一致,前缀形式操作符返回被增或者减量对象的引用。

 

 

2 区别前缀和后缀形式

由于前缀和后缀的形参数目和类型相同,普通的重载不能区别所定义的前缀操作和后缀操作

 

后缀的形式要接收一个额外、无用的int型参。使用后缀式时编译器自动提供0作为实参,它的唯一目的是使用后缀函数与前缀函数区分开。

 

3 后缀形式操作符

 

 

class CheckedPtr{

public:

     CheckedPtr operator++(int);

     CheckedPtr operator--(int);

 

};

CheckedPtr& CheckedPtr::operator++()

{

CheckedPtr ret(*this);

++*this;

return ret;

}

 

CheckedPtr& CheckedPtr::operator--()

{

CheckedPtr ret(*this);

--*this;

return ret;

}

 

 

先是保存状态,然后调用自己前面定义的前缀操作。

 

PS:以上全部内容来自《C++ Primer》

 

 

 

<think>我们被要求回答关于++--运算符在C/C++/JavaScript中的使用场景与区别。根据引用[1]我们知道:自增运算符和自减运算符有前置和后置之分,如a++(后置自增)、++a(前置自增)、b--(后置自减)、--b(前置自减)。主要区别在于:1.前置(++a,--b):先自增/自减,再使用变量的值。2.后置(a++,b--):先使用变量的值,再自增/自减。这个特性在C、C++和JavaScript中是一致的。使用场景:1.循环控制:在for循环中,我们常用i++++i来更新循环变量。2.表达式计算:在表达式中需要同时使用变量值并改变变量时。3.指针操作(C/C++):在指针遍历数组时,常用*p++来访问当前元素并移动到下一个。注意事项:1.避免在同一个表达式中对同一个变量多次使用自增/自减,因为这样会导致未定义行为(尤其在C/C++中)。2.在JavaScript中,自增/自减运算符可以用于数字类型的变量,如果用于非数字类型,会尝试转换为数字。示例(C++):inta=5;intb=a++;//b=5,a=6intc=++a;//a先变成7,然后c=7示例(JavaScript):letx=10;console.log(x++);//输出10,然后x变为11console.log(++x);//x先变为12,然后输出12另外,在C++中,我们可以重载自增和自减运算符,并且重载时需要区分前置和后置形式。根据引用[1]:后置自增运算符重载函数格式为:类名operator++(int)//这里的int是占位符,用于区分前置前置自增运算符重载函数格式为:类名operator++()在JavaScript中,没有运算符重载的概念。总结:-前置与后置的区别:执行顺序不同。-使用场景:循环、表达式、指针(C/C++)。-注意:避免复杂表达式中的歧义。下面我们给出详细解释和代码示例。</think>### `++` 和 `--` 运算符详解:C/C++/JavaScript 中的使用场景与区别 #### 核心概念 `++`(自增)和 `--`(自减)是**单目运算符**,用于对变量进行加1或减1操作,分为**前置**和**后置**两种形式: - **前置**:先执行运算,再返回值(`++a`, `--a`) - **后置**:先返回值,再执行运算(`a++`, `a--`) ```mermaid graph TD A[运算符类型] --> B[前置 ++a/--a] A --> C[后置 a++/a--] B --> D[1. 变量值±1<br>2. 返回新值] C --> E[1. 返回原值<br>2. 变量值±1] ``` #### 跨语言基础用法 | 语言 | 示例代码 | 输出结果 | |-------------|-----------------------------------|---------------| | **C/C++** | `int a=5; printf("%d", ++a);` | `6` (先增后返) | | | `int b=5; printf("%d", b++);` | `5` (先返后增) | | **JavaScript** | `let x=3; console.log(--x);` | `2` (先减后返) | | | `let y=3; console.log(y--);` | `3` (先返后减) | #### 关键区别 1. **执行顺序差异** ```javascript let n = 10; let m = n-- + 5; // 1. m = 10+5=15, 2. n=9 let p = --n + 5; // 1. n=8, 2. p=8+5=13 ``` 2. **表达式中的行为** ```c int arr[3] = {10, 20, 30}; int *ptr = arr; printf("%d", *ptr++); // 输出10,ptr指向arr[1] printf("%d", *++ptr); // 输出30,ptr指向arr[2] ``` 3. **类型转换规则** - JavaScript 中非数字类型会自动转换: ```javascript let s = "10"; s++; // 数值11,字符串转数字 ``` #### 典型应用场景 1. **循环控制** ```c // C/C++ 循环计数器 for(int i=0; i<10; i++) { /* 后置自增 */ } // JavaScript 遍历数组 let arr = [1,2,3]; for(let j=0; j<arr.length; ++j) { /* 前置自增 */ } ``` 2. **数据结构操作** ```c++ // C++ 链表遍历 Node* current = head; while(current != nullptr) { process(current->data); current = current->next; // 等效current++ } ``` 3. **性能敏感场景** ```c // 嵌入式系统寄存器操作 volatile uint32_t *reg = 0x40000000; (*reg)++; // 原子递增寄存器值 ``` #### 语言特性对比 | 特性 | C/C++ | JavaScript | |---------------------|--------------------------------|--------------------------------| | **指针支持** | ✓ (`ptr++` 移动指针) | ✗ (无指针) | | **运算符重载** | ✓ (可自定义行为)[^1] | ✗ | | **浮点数运算** | ✓ (`float f=1.5; f--;`) | ✓ | | **非数字类型转换** | ✗ (类型严格) | ✓ (`let s="10"; s++ → 11`) | #### 注意事项 1. **避免未定义行为** ```c int a = 5; a = a++ + ++a; // 未定义行为!不同编译器结果不同 ``` 2. **序列点规则** ```javascript // JavaScript 明确求值顺序 let b = 10; b = b++ * 2; // 结果20(所有语言统一) ``` 3. **浮点精度问题** ```javascript let f = 0.1; f++; // 1.1,但浮点运算可能有精度误差 ``` 4. **C++ 重载规范**[^1] ```cpp class Counter { public: Counter& operator++() { // 前置++ ++count; return *this; } Counter operator++(int) { // 后置++(int占位符) Counter tmp = *this; ++count; return tmp; } private: int count = 0; }; ``` #### 最佳实践建议 1. 循环控制优先使用后置形式(`i++`),语义更清晰 2. 复杂表达式中避免混用前置/后置 3. C++ 重载时返回引用(前置)或副本(后置) 4. JavaScript 中注意非数字类型的隐式转换
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值