ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

重载 C++ 中的下标 [] 运算符

2022-11-01 16:34:58  阅读:337  来源: 互联网

标签:C++ java JavaScript python 管理


序幕

最近,我决定在C++实施一棵红黑树作为个人项目。这已经存在并且实施起来很痛苦,几乎每行都发生段错误,但这既是红黑树(我在学校学习)的良好练习,也是C++(这总是很好的改进)。我让我的树处理 get、set、insert和 remove,世界一切都很好。但是,我缺少 C# 和 python 的简单语法,其中人们可以只索引地图,而不是使用笨拙的方法和点语法。在实践中,我们可以写点,这没什么大不了的,但这已经是一个实验,所以为什么不尝试让使用更容易(和更酷)呢?std::mapstd::setmap[key] = value

运算符重载

C++ 允许我们覆盖自定义类型的几乎所有运算符,例如 、、 和 订阅运算符 .C/C++ 中的正常行为是像 中一样自动执行指针算术和取消引用,但在语义上,它已成为索引(或下标,因此得名)数组、列表和映射的同义词。为类型重载此运算符的语法是使用签名创建方法。单数参数对应于方括号内的内容。此方法可以在地图上调用为+->=[]pointer[5] = *(pointer+5)<returnType> operator[](<paramType> <param>)mymap
<returnType> v = mymap[<param>];

树上的重载 []

像我们想要的那样实现订阅运算符有点困难,因为它需要提供两个功能,获取和设置。我们不能直接引用值字段,因为有特定的getter和setter,我们不希望它公开。因此,我们需要根据运算符的使用方式位置来改变行为。 应该调用 getter 方法,而应该调用 setter/insertion。确实没有办法使两个具有不同行为的重载(您可以自己尝试看看为什么),因此我们必须提出一个更棘手的解决方案。我们可以返回一个“代理”对象,该对象重载运算符并根据对其执行的操作调用正确的方法。int val = mymap[key];mymap[key] = val;operator[]

rbtree<K, V>::getSetProxy operator[](K key) {
    return getSetProxy(this, key);
}

现在调用变成了又变成了int val = mymap[key];int val = getSetProxy;mymap[key] = val;getSetProxy = val;

getSetProxy

此代理对象将根据用户尝试执行的操作处理获取和设置。代理的构造接受对树的引用,以便它可以执行操作,以及键,以便它知道在哪里获取/设置/插入。

设置的情况相当简单。我们将使用 assignment 运算符进行设置,因此我们可以重载它以调用 setter 方法。=

class getSetProxy {
    rbtree<K, V> *theTree;
    K key;
...
    void operator=(V value) {
        if (!theTree->setValue(key, value)) {
            theTree->insert(key, value);
        }
    }
...
}

赋值右侧的值在树中的键处设置或插入。

Get 有点棘手。C++中有一个运算符称为隐式强制转换运算符,签名 其中是要强制转换为的类型,只是表示此函数无法修改类。每当需要强制转换为其他类型时C++都会调用此函数。operator T() const;Tconst

myclass myobj = myobj();
int myint = myobj;
//          ^^^^^
//          implicit cast int() is called

所以在 中,将被调用。我们可以重载它以获得这样的功能:T val = getSetProxy;operator T()

class getSetProxy {
    rbtree<K, V> *theTree;
    K key;
...
    operator V() const {
        return theTree->getValue(key);
    }
...
}

将一切整合在一起

请原谅我滥用符号和平等以及所有即将发生的数学。

V value = mymap[key];

→→
V value = getSetProxy{key = key};V value = getSetProxy.operatorV();
V value = mymap.getValue(key);

mymap[key] = value;(为了简单起见,假设键不在地图中)

→→
getSetProxy{key = key} = value;getSetProxy{key = key}.operator=(value);
mymap->setValue(key, value)

结语

C++很有趣,因为您可以真正使语言成为您自己的语言。我能够采用笨拙的语法,并在几行(尽管有点棘手)代码中使其更熟悉。整个项目的代码,包括这个下标部分

标签:C++,java,JavaScript,python,管理
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有