以下代码会发生什么?
我想这不起作用,因为如果我想在b数组中添加一些内容,我会遇到分段错误,但我到底做了什么呢?
是否无法在构造函数中指定数组的大小?
class A {
public:
A() {
b[3];
}
private:
B b[];
};
答案 0 :(得分:4)
B b[]
这里是一个“flexible array member”,是编译器中的非标准扩展(取自C99),允许您将无界数组声明为类型中的最后一个成员。它仅在使用老式的C方式分配对象时(当你将参数填充到malloc
以为数组腾出空间时),并且应该避免使用它。在这种情况下,你没有为数组分配任何额外的内存,所以在你的构造函数体中,当你试图访问发生3'元素'的东西时,你正在调用UB。我将忽略其余答案的扩展名,因为它在C ++代码中确实没有地位。
是否无法在构造函数中指定数组的大小?
不,没有。
必须在编译时知道数组边界,因此在ctor体中你不会比在类定义中知道更多;您需要在成员的声明中编写维度:
class A {
B b[3];
};
如果维度是程序中的运行时数量,则需要存储指针,并在构造函数中将其指向动态内存块:
class A {
public:
A() : b(new B[3]) {}
~A() { delete[] b; }
private:
B* b; // same as `B b[]`! but far clearer
};
相反,我建议使用std::vector
:
class A {
public:
A() : b(3) {}
private:
std::vector<B> b;
};
答案 1 :(得分:2)
是。使用运算符new
:b = new B[3];
。将b
声明为B *b
。
当然,你需要在析构函数中delete[]
。
但更好的方法是使用std::vector
而不是数组,然后您不必担心预分配内存。
答案 2 :(得分:1)
C ++不支持在运行时确定大小的任何类型。因此,您只有在编译时确定数组大小的选项(可能通过非类型模板参数)或通过使b
指针并为{{1}分配内存来将数组移出对象。 (或者,更好的是,让标准库使用new
)为您执行此操作。
答案 3 :(得分:0)
这是不可能的 - 你期望sizeof(A)评估到什么?!如果您确实需要这样的功能,请使用动态分配,即构造函数初始化列表中的私有成员变量B * b,b(new B [3]),并删除[] b;在析构函数中。