使用构造函数将数组传递给对象后,值已更改(在 c++ 中)。我想不通为啥
Posted
技术标签:
【中文标题】使用构造函数将数组传递给对象后,值已更改(在 c++ 中)。我想不通为啥【英文标题】:After passing an array to an object using the constructer, the values have been changed (in c++). I can not figured why使用构造函数将数组传递给对象后,值已更改(在 c++ 中)。我想不通为什么 【发布时间】:2016-01-17 10:47:42 【问题描述】:我学会了如何在函数中传递一个(整数)数组,也知道如何在构造函数中进行。但是当我访问刚刚创建的对象中的数组时,值已经改变了。我几乎尝试了一切。我给新数组一个新名称,尝试使用 this-> 访问值并将数组存储为私有元素,以确保它不能以某种方式更改。我想我错过了一些重要的事情。
我想我不是发送数组,而是发送数组第一个元素的地址。但是,当在我创建数组的位置访问数组时,值是正确的。
最好用我做的例子来说明问题。我只是在初始化“Player Joyce”时将数组“keys”从对象“Game”发送到对象“Player”。我将此数组存储在名称“keyspressed”下。在初始化“Game game”和“Player Joyce”后,我从一个游戏循环中连续访问函数“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;
;
输出:
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
【问题讨论】:
你如何使用这些类?您能否尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们看?另外,an array of arrays is not the same as a pointer to a pointer. keys 是一个错字,但这不是问题所在。我想我可以做一个最小的例子,这将花费一些时间。但我只能理解如何更改私有数组“keyspressed”,因为它是私有的,我在“播放器”中没有任何其他方法 @F.Wessels 悬空指针和越界数组访问会导致各种损坏。private
仅防止故意修改。
ufo_main = new Texture("images/ufo/ufo.png", renderer, ufo_main_location, red, green, blue);
是可疑的,你将局部变量传递给texture
构造函数,而且Player
在复制时也不会正常运行,你最终会得到多个玩家拥有相同的 ufo_main 指针跨度>
我将示例更改为 MCVE。
【参考方案1】:
可能你最终得到的是悬空指针,虽然我不能肯定地说,因为你没有发布MCVE。
为避免此类问题,请停止使用原始指针。相反,使用具有值语义的容器。例如,您可以改用std::array<int, 5> keyspressed;
。您可能还想停止对 states
和 renderer
使用原始指针。
【讨论】:
我将示例更改为 MCVE。 @F.Wessels 好的。问题是您正在复制Game
对象,因此您最终会得到Player
具有指向Game
对象中的数组的悬空指针,这些数组现在已被销毁。要解决此问题,请停止使用原始指针。始终使用具有所有权语义的容器和/或智能指针。
那么游戏对象什么时候销毁呢?当我制作游戏对象并将其放入向量中时?我真的看不出来。此外,为什么不使用指针,如果你知道如何使用它们会很好用。因此,例如对于渲染器,每个窗口都有 1 个渲染器,所有子对象都获取渲染器的地址。我不明白为什么这是个问题。它就像一个魅力,当我不再需要它们时,我只需指向 NULL。
@F.Wessels games.push_back(Game());
创建一个游戏,然后在向量中创建该游戏的副本,然后销毁原始游戏。这会在向量中留下带有悬空指针的副本。不使用原始指针的原因是为了避免产生悬空指针的风险。显然,您当前对指针的使用并不“像魅力一样工作”,因为您遇到了您发布的这些问题。【参考方案2】:
我本来打算回答这个问题,但有人抢了我:p,但是我想建议您完全改变将按键和帧速率发送到播放器类的方式。在我的第一个游戏中,In 也是这样做的(通过函数传递它们)但是它很快就变得非常烦人,因为一个类可以访问某个变量的唯一方法是通过参数,这意味着我很快就会有大量的随机参数在每个函数中,这样他们就可以拥有他们需要的变量。
我建议将 Game 设为静态类,并为其提供一堆 get 函数来获取帧速率和按键等内容,这样您就可以避免在播放器中保留 key[5] 和 State 的副本并将它们从你的函数参数。
【讨论】:
那么你的意思实际上是制作一个大型游戏对象,然后让每个玩家从游戏中的 get 方法中访问所需的变量?或者您会考虑根本不制作 Player 对象吗? 是的,我在我的 android 游戏中设置它的方式是我有一个名为“App”的静态类,它包含一个指向“场景”类的指针向量(它允许不同的场景 - 你改变它们之间使用 App::gotoScene(id))。每个 Scene 类都有一个绘制、更新、构造函数和析构函数以及一些 onTouch、onDrag 等函数。所有这些函数都由包含主循环的 App 类协调并从当前场景调用函数,这样场景就不必担心这些事件是如何被检测到的——这对于跨平台应用程序很有用。 然后每个场景类都包含运行场景所需的数据,因此您的 Player 类将被实例化,例如 SceneGame 类。然后播放器使用 App::getFt() 获取帧时间。如果您想要多个播放器,那么 Player 类是有意义的。以上是关于使用构造函数将数组传递给对象后,值已更改(在 c++ 中)。我想不通为啥的主要内容,如果未能解决你的问题,请参考以下文章