如何通过引用获取对象的大小?

4
假设我有一个类:
class Foo {

:
:

}

我有另一个函数。
void getf( Foo &f) {

:
:

std::cout<<sizeof f<<std::endl;
}

在我处理数据并将许多数据分配给f(包含在Foo成员中的向量)之后,我需要知道f对象的大小。

然而,与我上面所做的一样,我总是得到16,这是一个引用的大小。

我做错了什么?怎么办?

谢谢!


1
我已经有一段时间没有写C++了 - 但是不是应该是 sizeof *f 吗? - ChrisF
3
f是一个引用而不是指针,对吗? - skydoor
1
嗯...你的引用是16个字节长?我见过的大多数只有4个。你的机器可以寻址多少内存? - James Curran
你期望得到什么结果?Foo 中有哪些成员? - EboMike
1
你究竟想做什么?请注意,在尝试找出自定义类型实例的大小时,必须考虑其他因素: "
  1. 所有非静态数据成员的大小
  2. 数据成员的顺序
  3. 字节对齐或字节填充
  4. 直接基类的大小
  5. 存在虚函数(使用虚函数的动态多态性)。
  6. 使用的编译器
  7. 继承模式(虚继承) "
- celavek
8个回答

8

sizeof函数返回类型的大小。通常情况下,例如在Vector中,类型的大小不一定包括类型可能指向的所有内容的累积大小。

class Foo {
   char* chars
}

无论chars指向单个字节还是指向40KB字符串,相同大小的结果都将被展示。


5
根据IBM参考文献,应用于引用的sizeof返回所引用对象的大小:

结果是所引用对象的大小。

因此,我认为问题不在于sizeof返回引用本身的大小,而是Foo持有指向其他类型的指针。
还要注意,sizeof不能告诉您vector(或使用堆的任何其他容器)内部数据的大小。请考虑以下示例:
struct Foo {
    std::vector<int> v;
}

int main(int argc, char **argv) {
    Foo foo;
    std::cout << sizeof(foo) << std::endl;
    foo.v.push_back(1);
    std::cout << sizeof(foo) << std::endl;
}

Output:
24
24

2
从C++标准:5.3.3/2 sizeof: 当应用于引用或引用类型时,结果是所引用类型的大小。 - Abhay
感谢你找到这个,Abhay。 :) - Justin Ardini

4
当我处理数据并将许多数据分配给f(包含在Foo成员中的向量)后,我需要f对象的大小。 sizeof是一个编译时操作。它为您提供变量或对象本身的固定大小。如果您的对象具有指向其他地方的内存的指针(这就是向量在内部使用的内容),sizeof将永远不会深入到它们中去确定它们所指向的大小。
如果您需要一些与运行时相关的对象总字节数的度量,则不能仅使用简单的sizeof。您必须添加所有部分的总和。例如:sizeof(f) + f.vector_member.size() * sizeof(whaterver_type_that_vector_contains)

1

sizeof 在这种情况下返回的是你的类的大小。你说你给 Foo 赋值了数据,但你没有定义 Foo。我猜它看起来像这样:

class Foo
{
public:
  string my_str;
  int* my_ints;
};

然后你可以像这样做:

Foo f;
f.my_str = "Hello, Foo.";
f.my_ints = new int[1000];

...并期望sizeof(f)现在将是Foo的大小,加上字符串的大小,再加上int数组的大小。但它不是这样的。Foo的大小从不改变,因为它没有char数组或int数组。相反,它有一个string对象(可能又指向一个char数组的指针)和一个指向int的指针。分配给字符串和int数组的内存不是“在”Foo中,而是由Foo指向的。


0
使用这个测试用例:
class Foo 
{ 
    char x [100];  
} ;

void getf( Foo &f) 
{ 
    std::cout<<"sizeof f:" << sizeof f<<std::endl; 
} 

我得到了打印的sizeof f:100。所以,你的代码是正确的;你只是解释错了。


0
如果你有一个像这样的类:
class Foo
{
    std::vector<int> intVec;

    // ....
};

sizeof 操作符是在编译时工作的,它只包含 vector 的实例数据成员的大小。它不会给出 vector 元素的总大小,因为这些元素存储在堆上,并由 vector 的某些私有成员指向。

如果您真的想要计算 vector 使用的总内存量,我认为没有一种可移植的方法来做到这一点。vector 实现可能分配未使用的内存,因此如果不查看实现,您就无法知道它正在做什么。


capacity()方法应该可以很好地告诉你向量中存储了多少内存。 - UncleBens

0

你能列举一下你的类F的结构吗?我怀疑你得到了正确的大小,sizeof会告诉你类的大小,也就是类的所有成员的大小(这基于对齐和排序以及你的编译器)。它不会告诉你包括元素在内的向量的大小,只是向量的引用的大小。


刚刚注意到kbrimington基本上发了同样的内容。我打字比较慢 :) - pstrjds

0

额外补充一点:

$8.3.2/3 规定 - “参考文献是否需要存储(3.7)未指定。”

因此,我们不应总是假设引用占用存储空间。当引用操作数被应用于 sizeof 时,返回原始 referand 的静态编译时 sizeof。


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