【赤石C++】不使用宏,实现一个幂运算符

admin 2026-02-02 00:07:35 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍C++中不使用宏实现幂运算符的方法。利用解引用运算符优先级高于乘法,通过重载operator和全局operator,将ab解析为a*(b)。针对初版破坏乘法逻辑的问题,引入PowProxy代理类区分运算重载,实现了语法糖与功能兼容的改进方案。 综合评分: 95 文章分类: 安全开发


cover_image

【赤石C++】不使用宏,实现一个幂运算符

原创

crackme.net crackme.net

crackme安全实验室

2026年2月1日 13:13 河南

这个幂运算符和我以前发的“逆序成员访问运算符”有异曲同工之妙

【赤石C++】不使用宏,实现一个“逆序”的成员访问运算符

在C++中,解引用运算符优先级高于乘法运算符,所以语句 a ** b 本质上是 a * (*b)

  • • 先对 b 执行解引用
  • • b 解引用的结果和 a 相乘

好了,看过上一篇文章的肯定有思路了

幂运算符

首先,创建一个类 MyInt 用于包装 int 类型(解引用运算符不能作用于基本类型,所以必须用类包装一下基本类型)

struct MyInt {
    int value;
};

然后,重载 MyInt 的解引用运算符,使其返回一个和自身相等的新类

struct MyInt {
    int value;

    MyInt operator*() const noexcept {
        return MyInt{ value };
    }
};

最后,全局重载乘法运算符

MyInt operator*(const MyInt& base, const MyInt& exp) noexcept {
&nbsp; &nbsp;&nbsp;return&nbsp;MyInt{&nbsp;static_cast<int>(std::pow(base.value, exp.value)) };
}

完整代码:

#include&nbsp;<cmath>
#include&nbsp;<iostream>

struct&nbsp;MyInt&nbsp;{
&nbsp; &nbsp;&nbsp;int&nbsp;value;

&nbsp; &nbsp; MyInt&nbsp;operator*()&nbsp;const&nbsp;noexcept&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;MyInt{ value };
&nbsp; &nbsp; }
};

MyInt&nbsp;operator*(const&nbsp;MyInt& base,&nbsp;const&nbsp;MyInt& exp)&nbsp;noexcept&nbsp;{
&nbsp; &nbsp;&nbsp;return&nbsp;MyInt{&nbsp;static_cast<int>(std::pow(base.value, exp.value)) };
}

std::ostream&&nbsp;operator<<(std::ostream& os,&nbsp;const&nbsp;MyInt& my) {
&nbsp; &nbsp; os << my.value;
&nbsp; &nbsp;&nbsp;return&nbsp;os;
}

int&nbsp;main()&nbsp;{
&nbsp; &nbsp; MyInt two{&nbsp;2&nbsp;}, three{&nbsp;3&nbsp;};
&nbsp; &nbsp; MyInt result = two ** three;

&nbsp; &nbsp; std::cout << two <<&nbsp;" ** "&nbsp;<< three <<&nbsp;" = "&nbsp;<< result << std::endl;
}

更好的实现

你可能发现了,将乘法运算符重载为计算幂后会影响正常的乘法

MyInt pow = two ** three;

// 会影响正常的乘法运算
MyInt multiply = two * three;

因此,创建一个额外的类PowProxy显然是更好的实现

  • • MyInt解引用后返回PowProxy
  • • 添加两个全局乘法重载,一个正常计算乘法,另一个接收PowProxy计算幂

#include&nbsp;<cmath>
#include&nbsp;<iostream>

struct&nbsp;PowProxy&nbsp;{
&nbsp; &nbsp;&nbsp;int&nbsp;exp;
};

struct&nbsp;MyInt&nbsp;{
&nbsp; &nbsp;&nbsp;int&nbsp;value;

&nbsp; &nbsp; PowProxy&nbsp;operator*()&nbsp;const&nbsp;noexcept&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;PowProxy{ value };
&nbsp; &nbsp; }
};

MyInt&nbsp;operator*(const&nbsp;MyInt& base,&nbsp;const&nbsp;PowProxy& pow)&nbsp;noexcept&nbsp;{
&nbsp; &nbsp;&nbsp;return&nbsp;MyInt{&nbsp;static_cast<int>(std::pow(base.value, pow.exp)) };
}

MyInt&nbsp;operator*(const&nbsp;MyInt& a,&nbsp;const&nbsp;MyInt& b)&nbsp;noexcept&nbsp;{
&nbsp; &nbsp;&nbsp;return&nbsp;MyInt{ a.value * b.value };
}

std::ostream&&nbsp;operator<<(std::ostream& os,&nbsp;const&nbsp;MyInt& my) {
&nbsp; &nbsp; os << my.value;
&nbsp; &nbsp;&nbsp;return&nbsp;os;
}

int&nbsp;main()&nbsp;{
&nbsp; &nbsp; MyInt two{&nbsp;2&nbsp;}, three{&nbsp;3&nbsp;};
&nbsp; &nbsp; MyInt pow = two ** three;
&nbsp; &nbsp; MyInt multiply = two * three;

&nbsp; &nbsp; std::cout << two <<&nbsp;" ** "&nbsp;<< three <<&nbsp;" = "&nbsp;<< pow << std::endl;
&nbsp; &nbsp; std::cout << two <<&nbsp;" * "&nbsp;<< three <<&nbsp;" = "&nbsp;<< multiply << std::endl;
}

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:crackme安全实验室 crackme.net crackme.net《【赤石C++】不使用宏,实现一个幂运算符》

评论:0   参与:  0