在C++中使用size_t是否是一个好习惯?

16

我看到有人在需要使用无符号整数时使用 size_t。例如:

class Company {
  size_t num_employees_;
  // ...
};

这是一个好的做法吗?其中一个问题是您必须包含<cstddef>。应该使用unsigned int甚至只是int吗?

对我来说,仅使用int听起来很有吸引力,因为它可以避免诸如此类的愚蠢错误(因为人们经常使用int):

for(int i = num_employees_ - 1; i >= 0; --i) {
   // do something with employee_[i]
}

1
我不认识任何一个人会从大小倒数到0来计算。 :| - GManNickG
1
我对强制类型转换的答案很好奇。如果您选择使用unsigned int或int,而这在您的系统上实际上并不是size_t,那么它可能需要进行转换,因此可能会有性能损失? - Troubadour
1
@GMan:如果有一个返回项目数量的函数,那么倒数计数将是有用的: for(int i=getNum()-1; i>=0; --i),因为如果你只是顺序计数,那么该函数将被多次调用(可能存在性能问题)。 - Frank
1
在这种经济环境下,你经常需要把员工数量缩减到最低。听说过“后进先出”吗? - Steve Jessop
顺便说一下,const正确性几乎从不允许编译器将函数调用移动到循环外。对const引用的函数调用不能保证始终返回相同的值。编译器不能假设它会这样做,因为它通常不能假设循环不会以某种方式修改const对象。它也可能不知道函数是否具有副作用。如果循环中的所有内容都可以内联(因此编译器知道没有通过全局变量进行修改),并且不存在指针别名的可能性,则可能可以。 - Steve Jessop
显示剩余13条评论
9个回答

15

size_t 可能与 int 大小不同。

对于像员工数量之类的东西,这种差异通常是无关紧要的;谁会有超过2^32个员工?然而,如果您需要一个表示文件大小的字段,并且您的文件系统支持64位文件,则应该使用size_t而不是int

请注意,对象大小(通过sizeof获取)的类型为size_t,而不是intunsigned int;相应地,有一个ptrdiff_t用于计算两个指针之间的差异(例如,&a[5] - &a[0] == ptrdiff_t(5))。


16
请使用 off_t 来表示文件大小,而不是 size_t。在 32 位系统上,size_t 是 32 位,而 off_t 是 64 位(如果启用了大文件支持)。 - Søren Løvborg
@Søren:非常好的观点。我会尝试想出另一个需要64位size_t的例子,然后更新我的帖子。欢迎您提供建议。 :-) - C. K. Young

7
在许多情况下使用size_t有助于提高可移植性。size_t并不总是"unsigned int",但它始终是可以表示给定平台上最大可能对象的大小。例如,某些平台具有16位整数大小,但使用32位指针。在这种情况下,如果您使用unsigned int来表示某个东西的大小,则会将其限制为65536字节(或其他元素),即使该平台可以处理更大的东西。
在您的示例中,我可能会使用typedef来定义32位或64位无符号整数,而不是使用int、unsigned int或size_t。

7
在这种情况下,不要使用它们中的任何一个。可以使用容器和迭代器或创建一个新的数据类型(例如员工数据库),该数据类型提供迭代器/范围访问。
至于无符号类型,Bjarne Stroustrup在《C++程序设计语言》中写道:
“无符号整数类型非常适合将存储视为位数组的用途。使用无符号整数代替int来表示正整数以获得更多位几乎从来不是一个好主意。通过声明变量为无符号类型来确保某些值为正数的尝试通常会被隐式转换规则所打败。”

3

size_t是用于指定值的内存大小(以字节为单位)的类型。它是sizeof表达式的类型。

只有在这个目的上才应该使用size_t,对于其他事情,您应该使用int或定义自己的类型。

另请参阅维基百科


2

你总是可以使用像这样的东西

employeeList.size();

或者

EmployeeList::size_type i = 0;

或者

EmployeeNumber number = employee.getNumber();

我的意思是,除非只是一些内部计算或算法,否则请封装int和其他类型。


0

在这种情况下,我会使用 unsigned int 或者 int。而 size_t 主要用于表示数据结构的大小。虽然员工数量有时可能是数据结构的大小,但并不一定;它可能只是一个计数。所以我会使用 int,但我可能不会过分强调。


0

虽然我不是专业人士,但当涉及到内存大小的时候我只使用size_t,这会提高代码的可读性。在其他情况下,我则使用unsigned int(或者其它类型)。


0
我认为,在C++中使用size_t不仅用于内存区域的大小,还用于索引(例如for循环中的索引变量)并不是一种坏的风格,因为在C++的参考文献中我们可以看到类似definitions的定义。
T& operator[](size_t i) const;

(此示例来自标准的unique_ptr模板类。)

因此,标准运算符旨在用于索引数组元素,其参数的类型正好是size_t


-1

在这种情况下,您不希望使用普通的int类型,因为雇员数量永远不会是负数,您希望编译器帮助您强制执行此规则,对吗?


5
我会很高兴如果编译器或运行时能够为此发出警告:num_employees_ = 0; --num_employees_; 但事实并非如此。 - Frank
@dehmann 但是你可以编写使用无符号整数作为参数的函数/方法,当用户传递普通整数时,他们将会收到警告。 - Piotr Dobrogost
2
@Piotr:不会的。在我所知道的所有编译器中,“void foo(unsigned int a){}int main(){int a=-1;foo(a);}”都不会有警告。传递负面文字才会收到警告。 - Steve Jessop
请查看此线程:https://dev59.com/93RA5IYBdhLWcg3w9yx0#765722 - GManNickG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接