C++中为什么不要直接使用指针传递数组
本篇内容主要讲解"C++中为什么不要直接使用指针传递数组",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++中为什么不要直接使用指针传递数组"吧!
不要直接使用指针传递数组
Reason(原因)
指针+大小风格的接口容易引发错误。同时,(指向数组的)单纯指针必须根据某些惯例被调用者推测(数组的)大小。
Example(示例)
Consider(考虑如下代码):
void copy_n(const T* p, T* q, int n); // copy from [p:p+n) to [q:q+n)
如果q指向的数组中的元素数目少于n时会发生什么?答案是会覆盖一些可能无关的内存。如果p指向的数组中元素的个数少于n会怎么样?答案是会读取某些无关的内存。无论哪种情况都是没有定义的行为,并且可能会引起严重的错误。
译者注:这类错误的难点在于发生问题的位置和引入问题的位置不知道离多远,还有可能发生的问题每次都不一样。
Alternative(可选项)
考虑使用清晰的span:
void copy(spanr, span r2); // copy r to r2
Example, bad(反面示例)
Consider(考虑以下代码):
void draw(Shape* p, int n); // poor interface; poor codeCircle arr[10];// ...draw(arr, 10);
向形参n传递10可能引发错误:最一般的惯例是假设[0:n)(左闭右开),但是哪里也没有说明。最不好的是对draw()的调用的编译行为:这里有一个从数组到指针的隐式转换(数组退化)和从Circle到Shape的隐式转换。draw()没有办法安全地遍历该数组,因为它无法知道元素的个数。
译者注:draw函数既没有办法知道数组的大小,也没有办法知道元素的类型。
可选项:使用确保元素数量的正确性并可以避免危险的隐式转换的支持类。例如:
void draw2(span
); Circle arr[10];
// ...
draw2(span
(arr)); // deduce the number of elements draw2(arr); // deduce the element type and array size
void draw3(span
);
draw3(arr); // error: cannot convert Circle[10] to span
draw2()(的两次调用)会向draw传递相同数量的信息。形成这个结果的原因是(draw2函数)会推断它的参数是Circles的range。
Exception(例外)
使用zstring和czstring来代替C风格,以0结尾的字符串。这种情况下使用来自GSL的str::string_view或者string_span以避免range错误。
译者注:这种情况下使用span会发生错误。
Enforcement(实施建议)
(Simple) ((Bounds)) Warn for any expression that would rely on implicit conversion of an array type to a pointer type. Allow exception for zstring/czstring pointer types.
(简单)((范围))任何表达式包含了从数组到指针的隐式转换,报警。作为例外,允许zstring/czstring类型的指针。
(Simple) ((Bounds)) Warn for any arithmetic operation on an expression of pointer type that results in a value of pointer type. Allow exception for zstring/czstring pointer types.
(简单)((范围))如果对指针的表达式进行算数操作并产生一个指针值,报警。指针类型为zstring/czstring时可以作为例外。
到此,相信大家对"C++中为什么不要直接使用指针传递数组"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!