sizeof()运算符在C++中的作用

what is sizeof() operator doing in C++

本文关键字:作用 C++ 运算符 sizeof      更新时间:2023-10-16

C中的sizeof()运算符在编译时给出其操作数的大小。它不计算其操作数。例如,

int ar1[10];
sizeof(ar1) // output 40=10*4
sizeof(ar1[-1]) // output 4
int ar2[ sizeof(ar1) ]; // generate an array of 40 ints.

当谈到C++模板类时,我发现了一些奇怪的结果。

template<typename T>
struct S{
    T a;
};
sizeof( S<int> )       // output 4
sizeof( S<bool> )      // output 1
sizeof( vector<int> )  // output 24
sizeof( vector<char> ) // output 24
sizeof( vector<bool> ) // output 40

我猜向量或其他STL容器上的sizeof取决于特定的环境。

问题1.sizeof是如何在C/C++中实现的?它不能是运行时函数。它是一个宏吗?(我在视频在线教程中学到的(。如果它是宏,它的#define是什么样子的?sizeof()何时执行?

问题2.如果我将成员方法void f(){}添加到struct S的定义中。sizeof(S<int>)仍然是4。结构的大小不应该增加吗?

问题3.STL容器是模板类。以vector为例,它有12个成员属性/类型和许多成员方法?sizeof( S<int> )的输出很容易解释。但我发现很难解释sizeof( vector<int> )的输出。模板类应在编译时实例化,编译器应完全了解类的大小,即vector<int>。所以sizeof()操作员应该知道。

根据问题1sizeof由编译器实现和评估。它不是一个宏,它总是提供编译时的结果。从概念上讲,您可以想象编译器用一个数字替换每个sizeof

根据问题2sizeof统计S的一个实例占用的存储量。方法不占用每个实例的存储空间,只有字段占用(因为它们每个实例存在一次(。然而,一个方法确实占用了某个地方的静态存储空间来保存函数的机器代码。

根据问题3:对于sizeof(vector<int>),编译器计算vector<int>的大小,并实例化该大小。如果您因为vector可以是可变大小而感到困惑:这是真的,但额外的存储是从堆中分配的,因此不会反映在sizeof应用于vector的结果中。

  1. sizeof不是宏。它是一个内置运算符,生成一个常量表达式,因此可以想象编译器在编译时只是用一个值为对象或类操作数大小的文字来替换它。

  2. 函数不会占用对象内部的空间。函数的代码没有存储在对象内部。

  3. 容器(如std::vector<int>(的大小是向量成员占用的内存量,加上一些实现定义的填充。它不包括向量通过持有指针"拥有"的任何内存。(请注意,向量的元素是而不是成员——当我说成员时,我指的是在std::vector类的定义中声明的成员。(因此,它与向量中有多少元素无关。