gpt4 book ai didi

c++ - &C::c 和 &(C::c) 有什么区别?

转载 作者:IT老高 更新时间:2023-10-28 13:57:38 30 4
gpt4 key购买 nike

下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。

#include <iostream>
#include <cstdio>

class C
{
public:
void foo() {
printf("%p, %p\n", &C::c, &(C::c)); // output value is 0x4, 0x7ffc2e7f52e8
std::cout << &C::c << std::endl; // output value is 1
}
int a;
int c;
};

int main(void)
{
C co;

printf("%p\n", &C::c); // output value is 0x4
std::cout << &C::c << std::endl; // output value is 1

// printf("%p\n", &(C::c)); // compile error, invalid use of non-static data member 'C::c'

co.foo();

return 0;
}
  1. 根据C++ operator Precedence:: 运算符的优先级高于 & 运算符。我认为 &C::c 等于 &(C::c),但输出却相反。为什么它们不同?
  2. &(C::c) 导致 main 编译出错,而 foo 函数没有,这是为什么呢?
  3. printfstd::cout&C::c的值不一样,这是为什么呢?

最佳答案

C++ 将两种形式的操作数与 & 区别开来。运算符,一般的左值和专门的(合格的)标识符。在 &C::c & 的操作数是一个限定标识符(即只是一个名称),而在 &(C::c)操作数是一个通用表达式(因为 ( 不能是名称的一部分)。

限定标识符形式有一种特殊情况:如果它引用类的非静态成员(如您的 C::c ),&返回一个特殊值,称为“指向 C 成员的指针”。见 here for more information about member pointers .

&(C::c)没有特殊情况。 C::c正常解析失败,因为没有对象可以得到c成员。至少在 main 中是这样的。 ;在 C 的方法中(就像你的 foo )有一个隐含的 this对象,所以 C::c实际上意味着 this->c在那里。

至于为什么 printf 的输出不同与 cout : 当你尝试用 << 打印成员指针时, 它被隐式转换为 bool , 产生 false如果它是一个空指针和 true否则。 false打印为 0 ; true打印为 1 .你的成员指针不为空,所以你得到 1 .这与普通指针不同,后者隐式转换为 void *并打印为地址,但成员指针不能转换为 void *所以唯一适用的过载operator<<bool 的那个.见 https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt#Notes .

请注意,从技术上讲,您的 printf调用具有未定义的行为。 %p需要 void *并且您正在向它传递不同类型的指针。在正常的函数调用中自动转换为 T *void *会踢,但是printf是一个变量参数函数,它不为其参数列表提供类型上下文,因此您需要手动转换:

printf("%p\n", static_cast<void *>(&(C::c)));

标准的相关部分是[expr.unary.op],说:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id. If the operand is a qualified-id naming a non-static or variant member m of some class C with type T, the result has type “pointer to member of class C of type T” and is a prvalue designating C​::​m. Otherwise, if the type of the expression is T, the result has type “pointer to T” [...]

关于c++ - &C::c 和 &(C::c) 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52940237/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com