当编译器需要知道 C(类)对象的大小时:例如,在堆栈上分配 C 或作为另一种类型的直接持有成员时
来自C++ 编码标准:101 条规则、指南和最佳实践
这是否意味着对于堆分配的对象,大小不是必需的?
Class C;//just forward declaration
C * objc = new C();
当编译器需要知道 C(类)对象的大小时:例如,在堆栈上分配 C 或作为另一种类型的直接持有成员时
来自C++ 编码标准:101 条规则、指南和最佳实践
这是否意味着对于堆分配的对象,大小不是必需的?
Class C;//just forward declaration
C * objc = new C();
不,此列表仅作为示例而非排除。显然,在堆分配中必须知道对象大小,以便分配正确的内存量。
要回答您的具体问题:
这是否意味着不需要堆分配的对象大小?
Class C;//just forward declaration C * objc = new C();
C++ 不会让你这样做。
即使它可以让您new
通过稍后神奇地解析大小来对不完整的类型执行 ' ' (我可以设想在链接器的合作下这在技术上是可行的),尝试将在编译时失败,因为至少 2原因:
运算符new
只能用于完整类型。从 C++98 标准 5.3.4 - “[分配的] 类型应是完整的对象类型,但不是抽象类类型或其数组”
编译器不知道存在哪些构造函数(并且可以访问),因此它也必须因此而失败。
对象大小由new
运算符计算:
Object *o = new Object();
您不需要明确告知new
对象大小,但它会计算它(使用sizeof
运算符)以便在堆上分配正确的空间量。
作为程序员,您几乎不需要知道 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
}
不,为了在堆上分配一个对象,你必须知道它的大小。
Foo *foo=(Foo *)malloc(sizeof(*foo));
编译器必须看到类的声明有两个原因:它必须知道它必须分配的大小(正如其他人已经指出的那样),还因为编译器必须知道如何构造对象:它是否具有默认构造函数,隐式定义了默认构造函数,没有默认构造函数?即使可以使用无参数构造函数创建对象,编译器也必须知道。