C++中的动态数组与Java相比

发布于 2025-01-29 02:34:03 字数 417 浏览 2 评论 0 原文

最近,在学习Java后,我开始学习C ++,并被指示制作一个动态数组,因此我尝试制作一个临时变量,其中包含我需要的内容,然后将其重新分配到我真正想要使用的变量中。

void Pile::grow(Stone s){
    Stone temp[getLength() + 1];
    for (int i = 0; i < sizeof(temp) / sizeof(temp[0]); ++i) {
        if (sizeof(temp) / sizeof(temp[0]) < 28){
            temp[i] = stoneArr[i];
        }
    }
        
    stoneArr = temp;
}

但是,由于某种原因,我无法理解的是,编译器给我一个无法重新分配的错误。

Recently, I started to learn C++ after I have learned Java, and I was instructed to make a dynamic array, so I tried to make a temp variable which contains what I need and then reassign it into the variable I actually want to use.

void Pile::grow(Stone s){
    Stone temp[getLength() + 1];
    for (int i = 0; i < sizeof(temp) / sizeof(temp[0]); ++i) {
        if (sizeof(temp) / sizeof(temp[0]) < 28){
            temp[i] = stoneArr[i];
        }
    }
        
    stoneArr = temp;
}

But the compiler is giving me an error that I cannot reassign it, for some reason I just can't understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哭泣的笑容 2025-02-05 02:34:03

void Pile :: grow(Stone S)

您在任何地方都不会使用 s 。您是否应该将其添加到您要创建的新数组中?

stone temp [getLength() + 1];

这在标准C ++中是不合法的。固定阵列的大小必须在编译时已知。

一些编译器将“可变长度数组”作为非标准扩展名支持,但是如果您需要编写便携式代码,请不要依靠它们。请参阅为什么不是c ++标准的变量length阵列的一部分?

在运行时动态分配数组,使用 new [] 运算符,例如:

Stone *temp = new Stone[getLength() + 1];
...
delete[] temp;

或者,使用标准 std :: vector 容器,例如:

#include <vector>

std::vector<Stone> temp(getLength() + 1);
...

for(int i = 0; i&lt; sizeof(temp)/sizeof(temp [0]); ++ i)

您不能在动态上使用此 size> sizeof trick数组,更不用说VLA了。 sizeof 仅在编译时而不是在运行时评估。

由于您正在从现有数组中复制值,因此请使用该数组的长度:

for (int i = 0; i < getLength(); ++i)

if(sizeof(temp)/sizeof(temp [0])&lt; 28)

硬编码 28 这里没有意义。实际上,如果检查需要完全删除。

stonearr = temp;

temp 是VLA时,此分配将无法使用。 stonearr 无论如何都不能成为VLA。

stonearr 需要是 Stone*指针 new [] 'D Array(通过遵循 3/5/0 ),或 std :: vector :: vector&lt; stone&gt; (首选)。

同样,请尝试尝试:

private:
    Stone *stoneArr;
    int arrLength;

...


Pile::Pile()
    : stoneArr(NULL), arrLength(0) {
}

Pile::Pile(const Pile &src)
    : stoneArr(new Stone[src.arrLength]), arrLength(src.arrLength) {
    for (int i = 0; i < arrLength; ++i) {
        stoneArr[i] = src.stoneArr[i];
    }
}

Pile::~Pile() {
    delete[] StoneArr;
}

Pile& Pile::operator=(const Pile &rhs) {
    if (&rhs != this) {
        Pile temp(rhs);
        std::swap(stoneArr, temp.stoneArr);
        std::swap(arrLength, temp.arrLength);
    }
    return *this;
}

int Pile::getLength() const {
    return arrLength;
}

void Pile::grow(const Stone &s){
    Stone *temp = new Stone[arrLength  + 1];
    for (int i = 0; i < arrLength; ++i) {
        temp[i] = stoneArr[i];
    }
    temp[arrLength] = s;
        
    delete[] stoneArr;
    stoneArr = temp;
    ++arrLength;
}

或:

#include <vector>

private:
    std::vector<Stone> stoneArr;

...

// std::vector follows the rule of 3/5/0, so let the
// compiler handle Pile(), Pile(const Pile &), ~Pile(),
// and operator= for you...

int Pile::getLength() const {
    return stoneArr.size();
}

void Pile::grow(const Stone &s){
    stoneArr.push_back(s);
}

void Pile::grow(Stone s)

You are not using s anywhere. Are you supposed to add it to the new array you are trying to create?

Stone temp[getLength() + 1];

This is not legal in standard C++. The size of a fixed array must be known at compile time.

Some compilers support "variable length arrays" as a non-standard extension, but do not rely on them if you need to write portable code. See Why aren't variable-length arrays part of the C++ standard?

To allocate an array dynamically at runtime, use the new[] operator instead, eg:

Stone *temp = new Stone[getLength() + 1];
...
delete[] temp;

Or, use the standard std::vector container instead, eg:

#include <vector>

std::vector<Stone> temp(getLength() + 1);
...

for (int i = 0; i < sizeof(temp) / sizeof(temp[0]); ++i)

You cannot use this sizeof trick on a dynamic array, let alone a VLA. sizeof is evaluated only at compile time, not at runtime.

Since you are copying values from an existing array, use the length of that array instead:

for (int i = 0; i < getLength(); ++i)

if (sizeof(temp) / sizeof(temp[0]) < 28)

Hard-coding a 28 here makes no sense. In fact, this whole if check needs to be removed completely.

stoneArr = temp;

This assignment will not work when temp is a VLA. And stoneArr can't be a VLA anyway.

stoneArr needs to be either a Stone* pointer to a new[]'d array (that is managed by following the Rule of 3/5/0), or a std::vector<Stone> (preferred).

With all of that said, try this instead:

private:
    Stone *stoneArr;
    int arrLength;

...


Pile::Pile()
    : stoneArr(NULL), arrLength(0) {
}

Pile::Pile(const Pile &src)
    : stoneArr(new Stone[src.arrLength]), arrLength(src.arrLength) {
    for (int i = 0; i < arrLength; ++i) {
        stoneArr[i] = src.stoneArr[i];
    }
}

Pile::~Pile() {
    delete[] StoneArr;
}

Pile& Pile::operator=(const Pile &rhs) {
    if (&rhs != this) {
        Pile temp(rhs);
        std::swap(stoneArr, temp.stoneArr);
        std::swap(arrLength, temp.arrLength);
    }
    return *this;
}

int Pile::getLength() const {
    return arrLength;
}

void Pile::grow(const Stone &s){
    Stone *temp = new Stone[arrLength  + 1];
    for (int i = 0; i < arrLength; ++i) {
        temp[i] = stoneArr[i];
    }
    temp[arrLength] = s;
        
    delete[] stoneArr;
    stoneArr = temp;
    ++arrLength;
}

Or:

#include <vector>

private:
    std::vector<Stone> stoneArr;

...

// std::vector follows the rule of 3/5/0, so let the
// compiler handle Pile(), Pile(const Pile &), ~Pile(),
// and operator= for you...

int Pile::getLength() const {
    return stoneArr.size();
}

void Pile::grow(const Stone &s){
    stoneArr.push_back(s);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文