【问题标题】:some confusions about pointer to an object关于指向对象的指针的一些混淆
【发布时间】:2020-07-28 08:08:55
【问题描述】:

问题一:指针值是什么?

指针类型的值是指向或超过对象末尾的指针,表示对象占用的内存中第一个字节([intro.memory])的地址54或结束后的内存中第一个字节对象占用的存储空间。

是不是说指针值就是一个对象的地址?

问题2:如何理解**指针值不变**?

[expr.static.cast]/13

否则,如果原始指针值指向对象a,并且存在与a指针可互转换的T类型对象b(忽略cv限定),则结果是指向b的指针。否则,指针值不会因转换而改变。

考虑下面的例子:

#include <iostream>
int main(){
   int a = 0;
   void* tmp = &a;
   char* obj = static_cast<char*>(tmp);
}

根据上面的引用,我们知道tmp的原始指针值指向a,而目标指针值指向一个char类型的对象,因为它们不是指针互转换的,因此句子指针值通过转换没有改变工作。是否意味着obj现在是指向char类型对象的指针并且对象的动态类型是@987654327 @,如果我误解了pointer value is unchanged,这句话是什么意思?

问题3:如何理解the result is a pointer to b

#include <iostream>
struct Data{
  int c;
}
int main(){
  Data d;
  void* tmp2 = &d;
  int* ptr = static_cast<int*>(tmp2);
}

我们知道tmp2的原始指针值指向d,所以原始指针值指向Data类型的对象,目标指针指向int类型的对象,并且这两个对象是指针互转换的,所以the result is a pointer to b这句话起作用了。是不是说现在ptr指向一个int类型对象的指针,对象的动态类型也是int

【问题讨论】:

  • 每个问题一个问题
  • @AsteroidsWithWings 我认为这些问题可以归入同一个问题
  • 我知道你知道,我每个问题都问一个问题

标签: c++ c++17 language-lawyer


【解决方案1】:

指针类型的值是指向或超过对象末尾的指针,表示该对象占用的内存中第一个字节([intro.memory])的地址或结束后的内存中第一个字节的地址对象占用的存储空间。

是不是说指针值就是一个对象的地址?

没有。

这个句子结构“A或B分别表示X或Y,”读作“条件A暗示X,或者条件B暗示Y。”

所以这句话的意思是两个

指针类型的值是指向对象的指针,表示该对象占用的内存([intro.memory])中第一个字节的地址...

指针类型的值是一个超过对象末尾的指针,表示该对象占用的存储空间结束后内存中第一个字节的地址。

分别允许作者对我在像这样展开时必须重复的序言进行去重。

而且,毕竟,即使是第一种情况,你的意思也不太正确。

表示一个指针,如果是一个指向对象的指针,表示该对象在内存中的第一个字节的地址。它没有说明任何指针的值,除非它是指向...对象的指针

这并不意味着每个指针值都是对象的地址,因为指针可以未初始化,或设置为nullptr,或设置为尚未转换为对象的原始分配的结果放置new。指针仍然可以通过指针保存您刚刚delete-d 的对象的地址。

我知道标准不是超级容易阅读,特别是如果您不习惯这种风格(或英语) - 但这意味着您需要努力阅读它仔细.

【讨论】:

  • 是的,总之指针值代表了一些东西的地址
  • 没有。如果你声明了一个指针并且不初始化它,它仍然有一个值。该值可能巧合地指向某个东西,但可能不是一个对象,并且可能是一种非法表示,会导致您的硬件上出现处理器陷阱,并且可能 没有任何物理映射,导致段冲突或总线错误。
  • 一个指向对象的指针指向“一些东西”。并不是每个指针都是指向对象的指针,而且引用的段落根本没有说明这些。
  • ,是的,我的意思是这些东西可以是一个对象或普通值
  • 或者根本不存在,或者代表内存映射的硬件设备,或者让你的程序崩溃,或者挂起你的操作系统,或者如果你试图取消引用它就会让你的 CPU 着火。它可能既不是对象也不是普通值。
【解决方案2】:

是不是说指针值就是一个对象的地址?

通俗地说,是的,这是完全正确的。更准确地说,它意味着指针值是一个地址。对象指针的值可以是对象的地址,也可以是无效的指针值、空值或不确定。

是不是说obj现在是指向char类型对象的指针了

是的。

如果我误解了指针值不变,这句话是什么意思?

简单地说,地址是一样的。 obj 是指向char 的指针,它指向存储int 对象的相同地址。但是obj 不是指向a 的指针。


据我了解,拥有指向对象 b 的指针与拥有值与 b 的地址相同的指针之间的区别在于,您始终可以通过指向 b 的指针间接合法地访问指向的对象.

仅仅拥有一个指向类型 T 的指针与另一个对象具有相同的值(即指向的地址)本身并不意味着它被定义为通过指针进行访问。即使该地址恰好存在该类型的对象(在这种情况下,您可以通过std::laundering 指针获取指向该对象的指针)。不过,在您的示例中,通过obj 间接是合法的,因为指向窄字符类型的指针是特殊的。

简而言之,指针总是指向一个地址。它可能会或可能不会指向该地址的对象。可能有多个对象具有相同的地址(仅在涉及子对象的情况下)。并非所有地址都始终包含对象。

【讨论】:

  • 无论你是否通过它访问,仅仅拥有这样一个指针并没有明确定义
  • @eerorika Dynamic type only pertains to pointers in an inheritance hierarchy,这不是真的,因为 ⟨glvalue⟩ 泛左值所指的最衍生对象的类型最衍生的对象类类型或非类类型称为最派生对象。,[[defns.dynamic.type]](timsong-cpp.github.io/cppwp/n4659/…
  • @Useless 但是,动态类型不仅仅指继承层次结构。
  • @Useless 我觉得不对。如果动态类型只是指继承层次,你怎么理解[[basic.lval]](timsong-cpp.github.io/cppwp/n4659/basic.lval#8) ?
  • @Useless 动态类型“glv​​alue所指的最衍生对象的类型”The definition of most derived object“最派生类类型或非类类型的对象称为最派生对象”。因此,它不仅仅在继承方面。非类类型的对象是大多数派生对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 2010-09-25
相关资源
最近更新 更多