是否在堆上创建对象需要对象的大小?

时间:2009-06-04 10:40:08

标签: c++ heap definition forward-declaration

  

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

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

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

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

6 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

回答您的具体问题:

  

这是否意味着分配了堆   对象大小没有必要吗?

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

C ++不会让你这样做。

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

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

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

答案 2 :(得分:2)

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

Object *o = new Object();

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

答案 3 :(得分: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
}

答案 4 :(得分:0)

没有。为了在堆上分配对象,您必须知道大小。

Foo *foo=(Foo *)malloc(sizeof(*foo));

答案 5 :(得分:0)

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