Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用构造函数将数组传递给对象后,值已更改(在c+;+;)。我不明白为什么_C++_Arrays_Constructor - Fatal编程技术网

C++ 使用构造函数将数组传递给对象后,值已更改(在c+;+;)。我不明白为什么

C++ 使用构造函数将数组传递给对象后,值已更改(在c+;+;)。我不明白为什么,c++,arrays,constructor,C++,Arrays,Constructor,我学习了如何在函数中传递数组(整数),也知道如何在构造函数中传递数组。但是当我访问刚刚创建的对象中的数组时,值已经更改。我几乎什么都试过了。我给新数组起了一个新名称,尝试使用this->访问这些值,并将数组存储为私有元素,以确保它不能以某种方式更改。我想我错过了一些重要的事情 我想我发送的不是数组,而是数组第一个元素的地址。但是,当在我创建数组的位置访问数组时,值是正确的 最好用我举的一个例子来说明这个问题。我只是在初始化“玩家乔伊斯”时将数组“键”从对象“游戏”发送到对象“玩家”。我以“key

我学习了如何在函数中传递数组(整数),也知道如何在构造函数中传递数组。但是当我访问刚刚创建的对象中的数组时,值已经更改。我几乎什么都试过了。我给新数组起了一个新名称,尝试使用this->访问这些值,并将数组存储为私有元素,以确保它不能以某种方式更改。我想我错过了一些重要的事情

我想我发送的不是数组,而是数组第一个元素的地址。但是,当在我创建数组的位置访问数组时,值是正确的

最好用我举的一个例子来说明这个问题。我只是在初始化“玩家乔伊斯”时将数组“键”从对象“游戏”发送到对象“玩家”。我以“keyspressed”的名称存储此数组。初始化“Game Game”和“Player Joyce”后,我从gameloop连续访问函数“render()”。我已经在不同的构造函数和函数中打印了数组的值

简而言之,我希望“keyspressed”的值始终保持{1,2,3,4,5}

我编辑了我的示例并制作了一个MCVE。我希望现在有人能更好地帮助我:p

#include<stdio.h>
#include<vector>

class Player {
    private:

    int *keyspressed;

    public:

    Player(int keys[5]) {
        keyspressed = keys;
        printf("%i - %i - %i - %i - %i from when Player is constructed\n", keyspressed[0], keyspressed[1], keyspressed[2], keyspressed[3], keyspressed[4]);
    }
    void render() {
        printf("%i - %i - %i - %i - %i from render() in Player\n", keyspressed[0], keyspressed[1], keyspressed[2], keyspressed[3], keyspressed[4]);
    }
};
class Game {
    private:

    std::vector<Player> players;

    int keys[5] = {1, 2, 3, 4, 5};

    public:

    Game() {
        players.push_back(Player(keys));        
        printf("%i - %i - %i - %i - %i from when Game is constructed\n", keys[0], keys[1], keys[2], keys[3], keys[4]);                
    }
    void render() {
        //Render all players
        for (int j = 0; j < players.size(); j++) {
            players[0].render();
        }
        printf("%i - %i - %i - %i - %i from render() in Game\n", keys[0], keys[1], keys[2], keys[3], keys[4]);
    }   

};
class Window {
    private:

    std::vector<Game> games;

    public:

    Window() {
    }
    void loadGame() {
        games.push_back(Game());
    }
    void render() {
        //render all games
        for (int i = 0; i < games.size(); i++) {
            games[i].render();
        }
    }
};

class Program {
    private:
    std::vector<Window> windows;

    public:
    Program() {
        //This program uses 1 window
        Window window;
        windows.push_back(window);

        //load game
        windows[0].loadGame();

        run();
    }

    void run() {
        //updates the renderer
        for (int i = 0; i < windows.size(); i++) {
            windows[i].render();
        }
    }
};


int main( int argc, char* args[]) {

    Program program;

    return 0;
};

也许你最终会得到一个悬而未决的指针,尽管我不能肯定,因为你没有发布一篇文章


为了避免此类问题,请停止使用原始指针。相反,使用具有值语义的容器。您可以使用按下的
std::array键。您可能还想停止使用原始指针来表示
状态
渲染器

我本想回答这个问题,但有人抢先回答了我:p,但是我想建议您完全改变向播放器类发送按键和帧率的方式。在我的第一个游戏中,我也这么做了(通过函数传递它们),但是它很快开始变得非常烦人,因为类访问某个变量的唯一方法是通过参数,这意味着我很快在每个函数中都有大量的随机参数,这样它们就可以拥有所需的变量


我建议将游戏设置为一个静态类,并为其提供一系列get函数,以获取帧率和按键等信息,这样您就不用在播放器中保存键[5]和状态的副本,并将它们从函数参数中删除。

如何使用这些类?你能试着创造一个新的世界并展示给我们看吗?另外,.keys是一个输入错误,但这不是问题所在。我想我可以举一个简单的例子,这需要一些时间。但我能理解私有数组“keyspressed”是如何改变的,因为它是私有的,我在“Player”@F.Wessels中没有任何其他方法悬空指针和越界数组访问会导致各种损坏
private
仅防止故意修改。
ufo_main=新纹理(“images/ufo/ufo.png”,渲染器,ufo_main_位置,红色、绿色、蓝色)
可疑,您将局部变量传递给
纹理
构造函数,并且
播放器
在复制时将无法正常工作,我把我的例子改成了一个MCVE。你的意思是,实际上制作一个大型游戏对象,然后让每个玩家从游戏中的get方法访问所需的变量?或者你会考虑不做一个球员对象吗?是的,我在我的Android游戏中设置的方式是,我有一个静态的类叫做“app”,它包含指向“场景”类的指针向量(允许不同的场景——你用APP::GoOsScOne(ID)来改变它们)。每个场景类都有一个draw、update、constructor和destructor函数以及一些onTouch、onDrag等函数。所有这些函数都由包含主循环的App类协调,并从当前场景调用函数,这样,场景就不必担心这些事件是如何被检测到的——这对跨平台应用程序很有用。然后,每个场景类都包含运行场景所需的数据,因此您的播放器类将在例如SceneGame类中实例化。然后,播放器通过App::getFt()获得帧时。如果您需要多个播放器,那么一个播放器类是有意义的。我将示例更改为MCVE.@F.Wessels OK。问题是,您正在复制
Game
对象,因此
Player
中的数组指针悬空指向
Game
中现在已被销毁的对象。要解决此问题,请停止使用原始指针。始终使用具有所有权语义的容器和/或智能指针。那么游戏对象何时销毁?当我制作游戏对象并将其放入向量中时?我真的看不出来。除此之外,为什么不使用指针呢?如果你知道如何使用指针,它们很好用。例如,对于渲染器,每个窗口都有一个渲染器,所有子对象都获得渲染器的地址。我不明白为什么这是个问题。它就像一个符咒,当我不再需要它们时,我只需指向NULL。@F.Wessels
games.push_back(Game())创建一个游戏,然后在向量中创建该游戏的副本,然后销毁原始游戏。这会在向量中留下悬空指针的副本。不使用原始指针的原因是为了避免创建悬空指针的风险。很明显,你目前使用的指针并不是“很有魅力”,因为你有这些问题。
1 - 2 - 3 - 4 - 5 from when Player is constructed
1 - 2 - 3 - 4 - 5 from when Game is constructed
237368672 - 32764 - 3 - 4 - 5 from render() in Player
1 - 2 - 3 - 4 - 5 from render() in Game