【问题标题】:Proper way to pass a pointer? c++传递指针的正确方法? C++
【发布时间】:2015-10-07 16:37:53
【问题描述】:

我有一个简单的问题,我不能 100% 确定。

假设我有一个实体类,它处理屏幕上的对象。假设 Entity 类有两个浮点变量,“x”和“y”(又名坐标)。也让我们说我传递的实体已经被声明并且在内存中。

我有另一个类处理相机移动。它需要以实体为中心。它以它为中心的实体可以改变,所以我相信我需要在这里使用一个指针。我在这里唯一要做的就是在需要时获取 X 和 Y 变量。这里没有任何改变。

我把它定义为

void StarField::ChangeFollowEntity(Entity* newFollowEntity) {
    followEntity = newFollowEntity;
}

其中 followEntity 也是一个实体类。我会调用 ChangeFollowEntity(..) 来更改实体。这真的正确吗?

我也看到了这个:

void StarField::ChangeFollowEntity(Entity newFollowEntity) {
    followEntity = &newFollowEntity;
}

在这两种情况下,followEntity 都被定义为 Entity* followEntity; .. 第二个例子在这里到底做了什么?据我了解, & 通常用作参考类型。也许一开始就做错了。

我很确定在这种情况下我不应该使用引用,因为 followEntity 发生了变化,我认为这些引用不能改变并且必须被定义。

所以我的问题是,我的第一个示例是否正确且正确的做法?第二个例子究竟做了什么?

【问题讨论】:

  • 第二个版本非常非常不正确...
  • 按照询问的顺序,是的,并悬挂一个可能稍后被取消引用并调用未定义行为的指针。
  • 有人想发表他关于引用是否有效的评论吗?
  • (const) 参考也应该有效。 void StarField::ChangeFollowEntity(const Entity& newFollowEntity)
  • 如果你在声明中使用 & 你会得到一个引用,但在 followEntity = &newFollowEntity; 的情况下 & 获取 newFollowEntity 的地址,提供完整的指针行为。 followEntity 被分配了 newFollowEntity 的地址。这种用法在函数的范围内是(部分)正确的,但是一旦函数返回,就会以灾难告终,正如答案中已经记录的那样。

标签: c++ pointers


【解决方案1】:

在你的第二个版本中::

void StarField::ChangeFollowEntity(Entity newFollowEntity) {
    followEntity = &newFollowEntity;
}

您通过值传递newFollowEntity,因此当您的函数从main 或任何地方调用时!制作对象的副本(使用复制构造函数)并发送到函数ChangeFollowEntity,在函数执行完成后,您的followEntity 具有COPY的地址对象,在函数调用完成后被销毁,所以你的指针 followEntity 悬空,如果你使用 followEntity 访问任何实体,这是未定义的行为

首先是正确的做法!!

【讨论】:

    【解决方案2】:

    第二个例子在这里究竟做了什么?

    您的第二个示例创建了一个Entity newFollowEntity 仅在该函数调用期间存在。

    存储那个变量的地址,然后销毁这个变量,留下一个dangling pointer

    这很糟糕。

    我很确定在这种情况下我不应该使用引用,因为 followEntity 发生了变化,我认为这些引用不能改变

    在这种情况下,您可以使用参考。可以更改引用的对象 - 您可能还记得 a reference cannot be reassigned.

    【讨论】:

      【解决方案3】:

      第二个示例执行以下操作:

      1. 当函数调用一个新的Entity对象newFollowEntiry 被创建并且传递给函数的任何内容都用于 构建它
      2. 然后获取该本地基于堆栈的对象的地址并 分配给followEntiry 大概存储。
      3. 函数执行完成后newFollowEntiry被销毁
      4. folowEntity 指针现在指向堆栈中的一个位置,其中 不再有Entity 对象。
      5. 错误

      【讨论】:

        猜你喜欢
        • 2013-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        相关资源
        最近更新 更多