【问题标题】:Why can't I add pointers?为什么我不能添加指针?
【发布时间】:2017-07-13 01:37:13
【问题描述】:

我的代码与此非常相似:

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator+(const Iterator& right)const
{
    return (this + &right);//IN THIS PLACE I'M GETTING AN ERROR
}

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator-(const Iterator& right)const
{//substracts one iterator from another
    return (this - &right);//HERE EVERYTHING IS FINE
}

err msg: Error  1   error C2110: '+' : cannot add two pointers

为什么我只在一个地方出现错误,而不是在两个地方?

【问题讨论】:

  • 添加指针意味着什么?如果您的家庭住址是 3472 Main,添加 2 之类的数字将为您提供 3474 Main,可能是邻居。但是将这两个地址相加会得到 6946。这是什么意思?

标签: c++ pointers


【解决方案1】:

742 长青台 + 1 = 743 长青台

742 长青台 - 1 = 741 长青台

743 常青台 - 741 常青台 = 2

743 长青台 + 741 长青台 = ???

【讨论】:

  • @Indrek 你建议第四行的结果应该是什么?添加两个地址根本没有意义。
  • :) 不错的答案。真的,我是认真的。
  • @Fred:1484 常青露台。呃。 ;-)(我同意@SigTerm:很好的例子)
  • 度提供了更清晰的解释,除了“度”可以表示绝对温度和温差,所以大多数人不明白它们是不同的单位。比如85度+5度差=90度100度-5度差=95度100度-95度=5度差100度+50度=?
  • @Jeremy 我认为“Evergreen Terrace”比“degrees”更适合,因为在单位方面不会有任何混淆。 《长青台》与单位无关。它只是一个从哪里开始计数的指示符,类似于数组的开头。
【解决方案2】:

C++中禁止指针加法,只能减去两个指针。

这样做的原因是两个指针相减给出了一个逻辑上可解释的结果——两个指针之间的内存偏移量。同样,您可以从指针中减去或添加整数,这意味着“向上或向下移动指针”。将指针添加到指针是很难解释的。结果指针代表什么?

如果您明确需要一个指向内存中某个位置的指针,该位置的地址是其他两个地址的总和,您可以将这两个指针转换为int,添加ints,然后转换回指针。但请记住,这个解决方案需要非常关注指针运算,这是您绝对不应该做的事情。

【讨论】:

  • ł 但正如您从 def 中看到的那样。在这些运算符中,我返回的是差异值而不是指针(迭代器),但我当然明白了,我同意你的看法。
  • 您正在返回一个差异,但除非您返回一个整数类型,否则您有一个隐式转换。 this + &right 必须在其结果转换为 LINT_rep::Iterator::difference_type 并返回之前进行评估,并且此评估失败,因为未为指针操作数定义运算符 +。这就是它失败的原因,即使它看起来很合理。
  • 强制转换为 int 是个坏主意,因为 sizeof(int) 可能不是 sizeof(void *)。使用类似 ptr_diff_t 的东西会是更好的选择。
  • 知道sizeof(ptrdiff_t) != sizeof(void *) 的编译器/运行时/操作系统组合。如果你打算尝试这个,我会说使用[u]intptr_t
  • 我当然有理由这么说,但你真的认为我现在还记得吗?但是我猜想这都是关于相对地址的——你需要添加一个基础才能正确使用它们。例如,在 Windows 进程中,这些称为“RVA”。
【解决方案3】:

减去两个指针可以得到它们之间的距离。两个指针相加会是什么结果?

【讨论】:

  • @KMKY,如果你可以做(date2 - date1),产生一个时间间隔,你也可以做(date2 + date1)吗?它会产生什么?
  • @cHao,谢谢你终于加入了真正的讨论。我的问题的重点是帮助 OP 自己发现原始问题的问题,并且不会让他们在此过程中感到愚蠢。当通过自己的推理过程而不是被灌输的答案时,学习会更加强大和持久。顺便说一句,与普通的缺乏知识相比,什么是严重缺乏关于指针的知识?
  • @cHao,说一个人首先通过 VBA 学习编程,然后决定尝试 C 或 C++。他们一边读一边写代码。在关于指针的章节中,他们发现您可以减去指针但不能添加它们。意识到他们的大脑没有点击,他们决定在程序员论坛上提出这个问题。你会建议这样的人不要费心学习 C 或 C++,因为这超出了他们的范围吗?请不要将“不懂”与“不懂”混为一谈。我们生来就严重缺乏对指针整个概念的了解。
  • @cHao:再来一点。 考虑添加指针的含义表示严重缺乏想象力。因此,我认为有人应该思考它是非常值得称赞的。一个人是否能够自己找出答案或需要帮助只是一个人在问题出现时所拥有的经验水平的函数。
  • @cHao,你可能玩游戏太久了。我教过很多人基本(不是 BASIC)编程,当人们第一次遇到指针时,指针远非显而易见。
【解决方案4】:

我想在您的示例中,您期望的结果是添加或减去指向要移动的偏移量的指针,而不是指向另一个指针。

在 C++ 中,您可以减去 2 个指针(获取它们之间的内存偏移量)或添加一个指向整数值的指针(将指针移动到另一个内存位置并按 value * sizeof(object_class) 递增)。仅添加 2 个指针在 C++ 中没有意义,但如果您确定要添加 2 个内存位置地址,只需将 then 添加为无符号整数值(使用类型转换)。

【讨论】:

  • 在 64 位编译器中 sizeof(x*) > sizeof(int) 除外。无法保证指针的大小与任何其他类型的大小相关。
【解决方案5】:

其他答案已经解释了为什么,你在做什么不起作用,但我的猜测是,你想为迭代器定义典型的 operator+,但在那次尝试中迷失了。

指针和标准随机访问迭代器都允许指针或迭代器前进一个整数值。对于迭代器,定义了一个operator+,它将整数值作为参数并返回一个迭代器。

LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance) const;

你可以将这样的操作符定义为一个方法,但是这个方法将允许你写

iterator + distance

但不是

distance + iterator

要使加法可交换,您必须定义一个朋友非成员函数,该函数将距离作为第一个参数,将迭代器对象作为第二个参数

friend LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance, const  LINT_rep::Iterator & rhs);

【讨论】:

    【解决方案6】:

    为什么我在一个地方出错,而不是两个地方?

    即使你被允许添加两个指针,这个:

     return (this + &right);
    

    不会指向任何地方。想一想 - this 可能类似于 0x00123456,而 &right 将在同一范围内(例如 0x00000000..0x80000000 - 即 0x00321321)。如果将它们相加,结果地址将指向远离两个变量(0x00123456 + 0x00321321 == 0x00444777,与“this”和&right 都太远),您可能会进入保留内存(win 时为 0x8xxxxxxx ) 等。此外,指针可能会溢出。这(可能)是被禁止的原因。

    如果你想给指针加点东西,就加整数。

    【讨论】:

      【解决方案7】:

      假设您有 2 个指针,并且您知道它们中的一个或两个都为空。如果两者都为 null,您希望返回不为 null 或 null 的那个。最简单的方法是对它们求和/异或。这是对指针求和的正确情况。

      【讨论】:

      • 标准不保证空指针全为零。
      • 4.10/1 “空指针常量是整数类型的整数常量表达式 (5.19) 纯右值,其计算结果为零或 std::nullptr_t 类型的纯右值。”只要您在一台机器上工作,其中值为 0 的整数类型的所有位都为零。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多