类型**的包装器的数组订阅运算符的返回类型是*&?

时间:2014-02-05 21:39:06

标签: c++ arrays pointers reference wrapper

假设我有一个类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 ...

2 个答案:

答案 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'不同,因此也可以更改其值。