2011-03-30 157 views
3

可能需要超载下标运算符的场景是什么?运算符超载[]

什么是assert函数与此有关?我在大多数情况下看到使用assert的下标重载,需要对此进行解释。

回答

7

您可能会在自定义容器上重载[]运算符,以提供访问元素的语法/语义更清晰的方式。

例如my_container[3] = 9;my_container.set(3, 9);

当然更为清楚,你可以重载[]做任何实质上,但你可能不应该。例如,您可以使my_object[3]my_object增加3,但在语义上012r运算符会传送按索引查找,并且最好让您的接口符合预期。

您可以使用assert进行快速和肮脏的边界检查;它会导致你的程序混乱死亡,这总是比引入细微的内存损坏更好。好处是,assert是一个可以从生产代码编译出来的宏,这意味着您可以支付边界检查开销的开销,而不是在生产中检查您的容器,而无需修改代码。

1

好吧,我对这方面的知识有限,我可以说,在这些类中有一系列元素时。 Vector/String例如。为了声明你可能想看看这个网站。 --LINK--

0

您可能想要更改索引的范围(例如,从1而不是从0开始编制索引),还是用一维数组表示高维数组?

3

你可能会考虑重载operator[]的类操作(索引(通过单个字段有意义,因为它是矢量(按位置索引)集或映射(按键索引)的情况)注意,如果存在多个维度,通过该指数,它可能是有意义的使用不同的运营商(operator()),为operator[]需要一个参数。你或许应该阅读Operator Overloading的C++ FAQ精简版条目。

一般assertoperator[](或任何其他操作员)无关assert是一种在运行时确定操作的某些先决条件已满足的方法,应该用于快速失败当您检测到某些不变量已损坏时,将难以通过

+1

只是一个说明,但如果有多个维度,传统的解决方案是返回一个代理,它也重载[]。人们可以争论这两种方法,但代理解决方案确实提供了与C风格数组阵列相同的语法,即c [i] [j]。 – 2011-03-30 16:13:51

+0

@James Kanze:就是说,在大多数情况下不是最好的主意。从链接的C++ FAQ中阅读[13.10](http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10)和以下几点。 – 2011-03-31 10:16:48

+0

@David Rodriguez常见问题表达了一位作者的意见。关于这个问题的意见 不同。 (在FAQ中的几个陈述,特别是那些关于性能的陈述,都是错误的。一个 解决方案很容易映射到另一个,因此性能永远不会成为 比另一个更喜欢的原因。)我更喜欢使用( )我---我的 受到巴顿和纳克曼的影响---但两种选择都是有效的, 值得一提,从我工作的地方来看, [] []选项似乎更受欢迎,并被认为是更“经典”的解决方案。 – 2011-03-31 10:56:11

1

断言绝对没有做与索引操作符operator[]本身

Assert用于检查调试版本中的先决条件/不变式,因此在投入生产之前会对其进行违规。为什么你似乎更往往比其他地方有注意到他们

索引运营商倾向于index out of range类型的情况下,这可能解释。我在每个参数化函数中至少使用一次assert,并且每个类使用几次(检查不变量)。

HTH

1

如果要实现一个类,它是一个集合或集合的包装你可能超载operator[]。对我而言,如果操作可以在常量或接近常量的时间执行,那么我只会重载operator[],因为这是数组索引执行的方式。使用它来查找散列表中的值可能是有意义的,但不能将其索引到链接列表中。

如果您发现在operator[]的实现中使用asserts,则很可能强制索引参数在集合的范围内。这,国际海事组织,是不正确使用assert,因为assert应该用来捕捉内部编程错误,而不是你的程序被称为错误的方式。最终用户或客户端应用程序不应该看到断言错误。另一种可能性是这个类只在内部使用,在这种情况下,断言错误会显示内部编程错误,而不是客户端传入的错误参数。

+0

好的提及时间限制;这就是阻止操作员在许多STL容器上发生的原因。虽然他们允许在“地图”的情况下记录时间。 – 2011-03-30 16:42:55