假设我有一个类A,其构造函数需要参数x。
class A
{
public:
int a;
A(int x) { a = x; std::cout << a << std::endl; }
~A() {}
};
现在我想分配一个A数组,并将其包装在另一个B类中(实际上它应该是A的二维数组,映射到一维数组,这就是为什么我需要包装它)。由于A的构造函数需要参数,我不能使用new [](... right?),所以我必须有一个A **。另外我不希望B知道x,所以我的B就像这样:
class B
{
private:
A** As;
const int n;
public:
B(int nn): n(nn) { As = new A*[n]; }
~B() { delete[] As; }
A* at(int i) { return As[i]; }
const A* at(int i) const { return As[i]; }
};
请注意,“订阅运算符”松散地表示at()函数。现在我的主要功能是这样的:
int main()
{
B b(3);
int x = -1;
for(int i = 0; i < 3; i++)
{
b.at(i) = new A(x);
}
return 0;
}
当我用g ++编译它时,它会在我的“新”行打印一个错误“左值作为赋值的左值”。然后我将at()的签名更改为
A*& at(int i)
它有效。
困扰我的是A *&amp;,这对我来说很奇怪......
这是A *&amp;我应该用什么?或者任何其他方式来处理一个对象数组,其构造函数需要参数?顺便说一下,我们的目标机器上没有c ++ 11和boost ...
答案 0 :(得分:3)
“或处理对象数组的任何其他方法,其构造函数需要参数?”
使用std::vector
,您不需要C ++ 11,也不需要任何其他库:
#include <vector>
...
std::vector<A> myObjects(n, A(0)); // objects will be constructed by calling A(0)
您的班级B
可能看起来如下:
class B
{
private:
std::vector<A> As;
const int n;
public:
B(int n): n(n), As(std::vector<A>(n, A(0))) { }
// no explicit destructor needed
// memory management is handled by std::vector object automatically
A& at(int i) { return As[i]; }
const A& at(int i) const { return As[i]; }
};
请注意,vector的元素存储在连续的内存块中,这些元素的生命周期与B
实例的生命周期相关联。一旦B
被破坏,向量也是如此,存储在其中的元素也是如此。如果n
是编译时已知的常量,您可能还会考虑使用std::array
。
答案 1 :(得分:0)
&amp; operator具有将函数参数或返回变量更改为引用的角色。
没有&amp;变量的值将被复制到时间变量中,因此原始变量对任何值变化都不敏感。
通过引用处理,参数将是原始变量,只有名称不同,但标记相同的内存块。
在此示例中,b.at(i)
语句将复制到临时常量变量中,该变量在= statement的左侧不可用。
但是通过引用该语句的返回,它指向原始As[i]
内存块,只有'name'不同,因此也可以更改其值。