【问题标题】:Array data is 'lost' after passing the array to another object将数组传递给另一个对象后,数组数据“丢失”
【发布时间】:2014-11-21 20:30:54
【问题描述】:

当我通过构造函数传递数组时,我遇到了一个问题,即我的数组中的对象丢失了。我的第一个猜测是我需要将其更改为指针数组,但这导致了段错误。我的下一个猜测是,我需要在传递数组数据后复制它,但这也没有用。问题代码如下:

宇宙对象:

class Universe {
public: 
    Star stars[]; int starsLength;
    Planet planets[]; int planetsLength;
public: 
    Universe(Star st[], int stl, Planet pl[], int pll) {
        stars < st; starsLength = stl;
        planets < pl; planetsLength = pll;
    }
    Universe() {

    }
public:
    void render() {        
        for(int i = 0;i < starsLength;i++) {
            //std::cout << "STAR: " << stars[i].location.x << "," << stars[i].location.y << " " << stars[i].size << " " << stars[i].color.r << "," << stars[i].color.g << "," << stars[i].color.b << "\n";
            renderCircle(stars[i].location, stars[i].size, stars[i].color);
        }
        for(int i = 0;i < planetsLength;i++) {
            renderCircle(planets[i].location, planets[i].size, planets[i].color);
        }
    }
    void renderCircle(Point location, float size, Color color) {
       glBegin(GL_LINES);
            glColor3f(color.r,color.g,color.b);
            glVertex2f(location.x+size, location.y+size);
            glVertex2f(location.x-size, location.y-size);
            glVertex2f(location.x-size, location.y+size);
            glVertex2f(location.x+size, location.y-size);
       glEnd();
    }
};

创建 Universe 并为其提供数组的方法:

Universe buildUniverse(int size, int seed) {
    Point bounds = Point{static_cast <float> (size),static_cast <float> (size)}; //0,0 to size,size
    int starCount = min(size/10,random(size/5));
    int planetCount = min(size/3,random(size));

    Star stars[starCount];
    Planet planets[planetCount];
    //std::cout << "-- Created " << starCount << " stars and " << planetCount << " planets...\n";

    for(int i = 0;i < starCount;i++) {
        Point location = {random(bounds.x),random(bounds.y)};
        Point velocity = {random(bounds.x/100.0f),random(bounds.y/100.0f)};
        float size = random(bounds.x/100.0f);
        float mass = random(size*(random(1.0f)+0.5f));
        Color color = {1.0f,1.0f,1.0f};
        stars[i].setStar(location,velocity,size,mass,color);
    }
    for(int i = 0;i < planetCount;i++) {
        Point location = {random(bounds.x),random(bounds.y)};
        Point velocity = {random(bounds.x/100.0f),random(bounds.y/100.0f)};
        float size = random(bounds.x/100.0f);
        float mass = random(size*(random(1.0f)+0.5f));
        Color color = {random(1.0f),random(1.0f),random(1.0f)};
        planets[i].setPlanet(location,velocity,size,mass,color);
    }

    Universe uni = {stars, starCount, planets, planetCount};
    std::cout << "Star in array: " << stars[0].location.x << "," << stars[0].location.y << " " << stars[0].size << " " << stars[0].color.r << "," << stars[0].color.g << "," << stars[0].color.b << "\n";
    std::cout << "Star passed to uni in an array: " << uni.stars[0].location.x << "," << uni.stars[0].location.y << " " << uni.stars[0].size << " " << uni.stars[0].color.r << "," << uni.stars[0].color.g << "," << uni.stars[0].color.b << "\n";
    return uni;
}

程序的输出:

Building universe...
Star in array: 39.922,39.155 0.167611 1,1,8.85715e-39
Star passed to uni in an array: 7.00649e-45,2.24208e-44 0.0282954 5.90446e-39,1.4013e-45,1.4013e-45
Initializing threaded renderer...
Starting simulation...

我做错了什么?

【问题讨论】:

  • 您是通过副本而不是引用传递数组吗?
  • stars &lt; st 应该做什么?
  • 编译?? (尤其是 Universe... 的第 1 和第 3 名成员)不在 coliru 上:coliru.stacked-crooked.com/a/790f218f52caa091
  • @newObjekt - 这是什么:Star stars[]?这不是 C++。
  • 你应该考虑使用std::vector

标签: c++ arrays object


【解决方案1】:

首先,您的代码不是有效的 C++。 C++ 中不存在使用[] 声明空数组。

所以第一件事就是把它变成有效的 C++,它仍然保留你想要完成的东西。一种解决方案是使用std::vector

#include <vector>
class Universe {
public: 
    std::vector<Star> stars;
    std::vector<Planet> planets;
public: 
    Universe(const std::vector<Star>& st, 
             const std::vector<Planet>& pl) : stars(st), planets(pl) {}
};

注意将非 C++ 代码替换为 std::vector。另请注意,我们使用initializer-list 初始化向量。

最后,请注意,我们不再需要将大小作为单独的成员变量进行保存。为什么?因为向量通过调用vector::size() 成员函数知道它的大小。例如:

  for(int i = 0;i < starsLength;i++) {

可以替换为

  for(int i = 0;i < stars.size();i++) {

在您的 buildUniverse 函数中,使用以下更改:

Universe buildUniverse(int size, int seed) {
    Point bounds = Point{static_cast <float> (size),static_cast <float> (size)}; //0,0 to size,size
    int starCount = min(size/10,random(size/5));
    int planetCount = min(size/3,random(size));

    std::vector<Star> stars(starCount);
    std::vector<Planet> planets(planetCount);

    //...
    Universe uni(stars, planets);

其余代码保持不变。现在,如果在调用创建Universe 之后,您看到向量没有传递正确的信息,那么请进一步查看。上面的代码符合“普通”的 C++,这样我们就可以进一步找出问题所在。

【讨论】:

  • 谢谢!我一定会在星期一试一试。是否有充分的理由在向量之类的库上使用标准数组类型?标准数组似乎非常有限。
  • C++ 标准数组的大小是固定的,而向量的大小是不固定的(可以调整大小而无需您进行任何内存管理)。即使您使用的是固定大小的数组,std::array 也是更好的选择。
猜你喜欢
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 2017-11-15
  • 2015-07-14
  • 1970-01-01
  • 2019-09-29
相关资源
最近更新 更多