【问题标题】:Why different behavior for "TYPE* const" pointers?为什么“TYPE*​​ const”指针的行为不同?
【发布时间】:2011-04-14 05:58:38
【问题描述】:

下面的代码正在处理一个TYPE* const 指针。

struct D {
  void Check ()
  {
    D* const p = new D; // 2nd test is "p = 0;"
    cout<<"p = "<<p<<endl;
    (D*&)p = new D;
    cout<<"p = "<<p<<endl; // prints 0, "p = 0;" at declaration
  }
};

int main ()
{
  D o;
  o.Check();
}

我的问题是,

  1. 如果您使用0 进行初始化,那么即使下次类型转换也不起作用。进行这种类型转换是未定义的行为吗?
  2. this指针也是TYPE* const类型,那为什么编译器不允许this做同样的操作呢?

【问题讨论】:

    标签: c++ pointers constants this undefined-behavior


    【解决方案1】:

    这样的类型转换是未定义的行为吗?

    是的。

    (D*&)p = new D;
    

    它调用未定义的行为,因为它试图更改 const 指针。

    回想一下,D* const p 声明了一个变量 p,它是一个指向非常量 D 的 const 指针。

    【讨论】:

    • 我的意思是 (D*&)p。但正如你所说,它需要 p 的地址,我怀疑这种说法。因为它不是 (D*)&p!我正在参考指针 p。另外,为什么限制this,因为那也是同一类型。
    【解决方案2】:
    D* const p = 0;
    

    这个声明说p 是一个指向D 的指针,它是不变的,也就是说它永远不会改变。它总是 0。

    cout<<"p = "<<p<<endl;
    

    在这里你显示 p 的值,你之前说它总是为 0。猜猜为什么显示 0!

    【讨论】:

    • 如果不使用0(如上面的真实代码)进行初始化,cout 都会输出不同的内存位置。如果您使用0 进行初始化,那么cout 都将输出0!
    • 那只是因为编译器无法判断地址是什么。但是,您不能尝试更改它,因为您承诺它应该是不变的。就像 Nawaz 所说,这是未定义的行为。任何事情都有可能发生!
    【解决方案3】:
    1. 正如其他人所说,这是未定义的行为,因为它试图修改 const 对象。如果将其初始化为零,则编译器可能将其视为编译时常量,并忽略任何修改它的尝试。或者它可能会做一些完全不同的事情。

    2. this 不是TYPE * const 类型的普通变量;它是TYPE * 类型的右值表达式。这意味着它根本不能用作赋值表达式的目标,也不能绑定到非常量引用。

    【讨论】:

    • 一些编译器将this 实现为TYPE *const,这对他们来说已经足够右值了。
    • @SimonRichter 哪些编译器? (这意味着他们接受&amp;this。)
    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 2011-01-14
    • 2014-05-30
    • 2017-06-08
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多