繁体   English   中英

如何将数组传递给构造函数?

[英]How do I pass an array to a constructor?

我想将一个数组传递给构造函数,但只传递第一个值 - 其余的看起来像垃圾。

这是我正在研究的简化版本:

#include <iostream>

class board
{
    public:
        int state[64];
        board(int arr[])
        {
            *state = *arr;
        }
        void print();
};

void board::print()
{
    for (int y=0; y<8; y++)
    {
        for (int x=0; x<8; x++)
            std::cout << state[x + y*8] << " ";
        std::cout << "\n";
    }
}

int main()
{
    int test[64] = {
        0, 1, 2, 3, 4, 5, 6, 7,
        1, 2, 3, 4, 5, 6, 7, 8,
        2, 3, 4, 5, 6, 7, 8, 9,
        3, 4, 5, 6, 7, 8, 9,10,
        4, 5, 6, 7, 8, 9,10,11,
        5, 6, 7, 8, 9,10,11,12,
        6, 7, 8, 9,10,11,12,13,
        7, 8, 9,10,11,12,13,14 };

    board b(test);
    b.print();

    std::cin.get();
    return 0;
}

有人可以解释为什么这不起作用以及如何正确传递数组? 另外,我不想复制数组。 (我是否真的必须将每行代码缩进4个代码?这非常繁琐。)

在这种情况下,最好使用对数组的引用:

class board
{
    int (&state)[64];

public:
    board(int (&arr)[64]) 
        : state(arr)
    {}

    // initialize use a pointer to an array
    board(int (*p)[64]) 
        : state(*p)
    {}


    void print();
};

一些优点 - 不复制数组,编译器将强制传入正确的大小数组。

缺点是初始化board对象的数组需要至少与对象一样长,并且对象外部的数组所做的任何更改都会“反映”到对象的状态。 但是如果你使用指向原始数组的指针也会出现这些缺点(基本上,只复制数组会消除这些缺点)。

另一个缺点是你不能使用指向数组元素的指针来创建对象(如果参数声明中没有提供数组大小,则数组函数参数'衰减')。 例如,如果数组通过一个实际上是指针的函数参数传递,并且您希望该函数能够创建引用该数组的board对象。

尝试将数组传递给函数会导致将指针传递给数组的第一个元素。

您不能分配数组,并且像T[]这样的参数与T*相同。 所以

*state = *arr;

被取消引用指针statearr和分配的第一要素arr到的第一个元素state

如果你想要做的是将值从一个数组复制到另一个数组,你可以使用std::copy

std::copy(arr, arr + 64, state); // this assumes that the array size will
                                 // ALWAYS be 64

或者,您应该查看std::array<int> ,其行为与您假设数组的行为完全相同:

#include <array>
#include <algorithm>
#include <iostream> 

class board
{
    public:
        std::array<int, 64> state;

        board(const std::array<int, 64> arr) // or initialiser list : state(arr)
        {
            state = arr; // we can assign std::arrays
        }
        void print();
};

void board::print()
{
    for (int y=0; y<8; y++)
    {
        for (int x=0; x<8; x++)
            std::cout << state[x + y*8] << " ";
        std::cout << "\n";
    }
}

int main()
{
    // using this array to initialise the std::array 'test' below
    int arr[] = {
        0, 1, 2, 3, 4, 5, 6, 7,
        1, 2, 3, 4, 5, 6, 7, 8,
        2, 3, 4, 5, 6, 7, 8, 9,
        3, 4, 5, 6, 7, 8, 9,10,
        4, 5, 6, 7, 8, 9,10,11,
        5, 6, 7, 8, 9,10,11,12,
        6, 7, 8, 9,10,11,12,13,
        7, 8, 9,10,11,12,13,14 };

    std::array<int, 64> test(std::begin(arr), std::end(arr));

    board b(test);
    b.print();

    std::cin.get();
    return 0;
}
#include <iostream>

class board
{
    public:
        int * state;    //changed here, you can also use **state
        board(int *arr)               //changed here
        {
          state = arr;
        }
        void print();
};

void board::print()
{
    for (int y=0; y<8; y++)
    {
        for (int x=0; x<8; x++)
            std::cout << *(state + x + y*8) << " ";   //changed here
        std::cout << "\n";
    }
}

int main()
{
    int test[64] = {
        0, 1, 2, 3, 4, 5, 6, 7,
        1, 2, 3, 4, 5, 6, 7, 8,
        2, 3, 4, 5, 6, 7, 8, 9,
        3, 4, 5, 6, 7, 8, 9,10,
        4, 5, 6, 7, 8, 9,10,11,
        5, 6, 7, 8, 9,10,11,12,
        6, 7, 8, 9,10,11,12,13,
        7, 8, 9,10,11,12,13,14 };

    board b(test);
    b.print();

    std::cin.get();
    return 0;
}

或者你可以用它作为:

class board
{
    public:
        int state[64];
        board(int arr[])
        {
            for(int i=0;i<64;++i)
               state[i] = arr[i];
        }
        void print();
};

编辑1:稳定的解决方案

class board
    {
        public:
            int * state;    //changed here, you can also use **state
            board(int *arr)               //changed here
            {
              state = new int[64];
              for(int i=0;i<64;++i)
                   state[i] = arr[i];
            }
            void print();
    };

*state = *arr; 正在使用dereferencing,它返回指针地址处的值。

这与state[0] = *arr; 因为*arr是一个int

有关指针的信息,请参阅此文章 请参阅参考部分。

要解决此问题,您需要执行此操作:

for (int i = 0; i < 64; i++) state[i] = arr[i]

数组的名称是其中第一个元素的地址。

因此,行*state = *arrstate[0]设置为arr[0]

从现在开始,你已经将state定义为int state[64]; stateint类型的const pointer ,其地址不能更改。

你可以把它改成int *state; 然后state = arr将起作用。

* arr给出存储在arr [0]的值。 在c ++中,数组的名称是指向数组中第一个元素的指针。

因此,当您执行* state = * arr时,将值存储在变量状态的arr [0]中。

现在,如果你想传递数组而不必显式复制每个元素,我建议你在你调用的方法中创建另一个相同大小的数组,然后从调用者传递数组的名称,实质上:

methodWhereArrayisPassed(int *arrayName)
{
    int arrCopy[64];
    arrCopy = arrayName;

// Do more stuff here
}

methodWhichPassesArray()
{
    // do stuff here
    int arr[] = {
       0, 1, 2, 3, 4, 5, 6, 7,
       1, 2, 3, 4, 5, 6, 7, 8,
       2, 3, 4, 5, 6, 7, 8, 9,
       3, 4, 5, 6, 7, 8, 9,10,
       4, 5, 6, 7, 8, 9,10,11,
       5, 6, 7, 8, 9,10,11,12,
       6, 7, 8, 9,10,11,12,13,
       7, 8, 9,10,11,12,13,14 };

methodWhereArrayisPassed(arr);

// do stuff here
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM