【问题标题】:Why is the pointer value in the function different to the one passed in as an argument?为什么函数中的指针值与作为参数传入的指针值不同?
【发布时间】:2013-05-15 04:33:33
【问题描述】:

我有以下构造函数:

MutexWrapper::MutexWrapper(Mutex * pMutex)
{
  DebugPrint("0x%x", pMutex); // displays 0x1f83e54
}

它在以下函数中被调用:

void OnReviewBuffer_Callback( void * pUserData )
{
  ReviewBuffer * thePointer = (ReviewBuffer *) pUserData;

  DebugPrint("0x%x", thePointer); // this displays 0x1f83e48

  MutexWrapper theMutexWrapper(thePointer);
}

很遗憾,我无法提供ReviewBuffer 的完整定义 - 但我希望以下内容就足够了:

class ReviewBuffer  : public StreamConsumer_Base, public Mutex
{
  ...
};

问题是当我打印出thePointer 时,我得到0x1f83e48,但从构造函数内部打印的值是0x1f83e54

为什么指针值不同 - 这与传递指针副本中的值传递有关吗?

【问题讨论】:

  • @John Dibling,我从问题中删除了 IN - 它的#define'd 扩展为空(这纯粹是为了读者的利益)。
  • 克里斯是的,这正是它的用途。
  • @BeeBand 你确定在theMutexWrapper 声明之前的DebugPrint("0x%x", thePointer); 给出了不同的值吗?
  • 请告诉我们调用前打印指针的代码,以及这个指针的确切定义。我怀疑这是一个继承/多态性问题。
  • @BeeBand:是的,这就够了,这确实是我的想法。我正在写一个答案。

标签: c++ pass-by-value


【解决方案1】:

您的类ReviewBuffer 使用多重继承:

class ReviewBuffer  : public StreamConsumer_Base, public Mutex
{
  ...
};

类的内部布局(可能*)如下所示:

Offset 0    class StreamConsumer_Base
            ... contents of that class (12 bytes including alignment: 0x1f83e54 - 0x1f83e48)
Offset 12   class Mutex
            ... contents of that class (unknown size)

(*) 可能 因为标准中没有任何规定。这只是编译器实现它的常用方式。

当您最初打印thePointer 时,它指向ReviewBuffer 对象,即。类的偏移量 0。但是当你将它传递给你的函数时,编译器会自动调整指针以指向ReviewBufferMutex 部分。由于 Mutex 部分的偏移量为 12,因此指针的值不能相同(想想看:如果相同,它不会指向 Mutex,而是指向 ReviewBuffer 或 @ 987654331@).

【讨论】:

    【解决方案2】:

    您的非默认构造函数MutexWrapper::MutexWrapperMutex* 指针作为参数。您的函数 OnReviewBuffer_Callback 将提供的 void* 指针转换为 ReviewBuffer* 指针。将ReviewBuffer* 指针作为参数传递给MutexWrapper::MutexWrapper(Mutex*) 的唯一方法是ReviewBufferMutex 的派生类。如果ReviewBuffer 也继承自其他类,则将ReviewBuffer* 指针向下转换为Mutex* 指针可能会导致指针具有与原始地址不同的地址。根据最新的编辑,这正是正在发生的事情。 ReviewBuffer 使用多重继承。

    【讨论】:

      【解决方案3】:

      在 C++ 中和在 Java 中一样,指针是按值传递的。 引用传递是用词不当。

      当然,指针指向同一个地址变量,看起来整体是通过引用传递的,但是……不是。

      【讨论】:

      • “传递引用是一个误称 [在 C++ 中]”捍卫这个说法
      • 这里没有引用。指针按值传递,但(显然)在函数中具有不同的值。 (而且我不知道您所说的“用词不当”是什么意思;通过引用在 C++ 中有很好的定义,只是这里没有发生)。
      • 这只有在调试打印打印指针的地址时才成立,但看起来它应该打印指针的值。
      • @JohnDibling 我是一个在按值传递指针时绝对避免说“按引用传递”的人。该术语来自 C,但在应用于 C++ 时会令人困惑,特别是因为我们实际上有引用类型。 Mutex 没有通过引用传递;它根本没有通过。事实上,(按值)传递的指针甚至不需要指向Mutex 对象。不过,这实际上只是对如何标记问题的批评,而这个答案并不真正适用于问题本身。
      • @JohnDibling 这个问题被标记为pass-by-reference,不过,好像提问者认为传递指针是通过引用传递(这 C 程序员所说的)。这就是 Mik378 在他的回答中所说的“通过引用是用词不当”。
      猜你喜欢
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多