1

当编译器需要知道 C(类)对象的大小时:例如,在堆栈上分配 C 或作为另一种类型的直接持有成员时

来自C++ 编码标准:101 条规则、指南和最佳实践

这是否意味着对于堆分配的对象,大小不是必需的?

Class C;//just forward declaration
C * objc = new C();
4

6 回答 6

5

不,此列表仅作为示例而非排除。显然,在堆分配中必须知道对象大小,以便分配正确的内存量。

于 2009-06-04T10:41:48.930 回答
3

要回答您的具体问题:

这是否意味着不需要堆分配的对象大小?

Class C;//just forward declaration
C * objc = new C();

C++ 不会让你这样做。

即使它可以让您new通过稍后神奇地解析大小来对不完整的类型执行 ' ' (我可以设想在链接器的合作下这在技术上是可行的),尝试将在编译时失败,因为至少 2原因:

  1. 运算符new只能用于完整类型。从 C++98 标准 5.3.4 - “[分配的] 类型应是完整的对象类型,但不是抽象类类型或其数组”

  2. 编译器不知道存在哪些构造函数(并且可以访问),因此它也必须因此而失败。

于 2009-06-05T06:25:49.420 回答
2

对象大小由new运算符计算:

Object *o = new Object();

您不需要明确告知new对象大小,但它会计算它(使用sizeof运算符)以便在堆上分配正确的空间量。

于 2009-06-04T10:42:49.910 回答
2

作为程序员,您几乎不需要知道 C++ 中对象的大小。例如:

class A {
    ...  // member data
};

void f() {
    A a;              // allocate on stack
    A * p = new A;    // allocate on heap
}

在这两种情况下,程序员都不需要知道大小的知识——编译器当然需要知道它。

请注意,无论您如何创建一个对象,编译器在创建时都必须知道它的大小:

class B;     // forward declaration - no size:

void f() {
    B b;              // compilation error
    B * p = new B;    // compilation error
}
于 2009-06-04T10:43:27.833 回答
0

不,为了在堆上分配一个对象,你必须知道它的大小。

Foo *foo=(Foo *)malloc(sizeof(*foo));
于 2009-06-04T10:43:28.007 回答
0

编译器必须看到类的声明有两个原因:它必须知道它必须分配的大小(正如其他人已经指出的那样),还因为编译器必须知道如何构造对象:它是否具有默认构造函数,隐式定义了默认构造函数,没有默认构造函数?即使可以使用无参数构造函数创建对象,编译器也必须知道。

于 2009-06-04T13:46:55.000 回答