C++中指向成员函数的指针

问题描述 投票:0回答:2

我在这一行遇到问题

   std::cout << &X::a << std::endl;
这一行 print 1 应该打印 &X::a 的地址

这是我的代码

#include <iostream>
#include <string>
#include <iomanip>

class X
{
public:
    int a;
    void f(int b);
};

void X::f(int b)
{
    std::cout << "the value of b is " << b << std::endl;
}

void add()
{
    std::cout << "Hello this function hello" << std::endl;
}
int main()
{
    void (*funcPtr)(void) = add;
    funcPtr();
    int X::*ptrnumber = &X::a;
    void (X::*ptrfunction)(int) = &X::f;
    X xobj;
    xobj.*ptrnumber = 10;
    std::cout << "the vslue of a is " << xobj.*ptrnumber << std::endl;
    (xobj.*ptrfunction)(20);
    std::cout << std::hex << &X::a << std::endl;
    //std::cout << funcPtr << std::endl;
}

我用不同的编译器c++编译,但我有相同的输出
我显示了这个“M1Xi”的类型,我不知道这个数据类型

c++ oop pointers function-pointers pointer-to-member
2个回答
3
投票

&X::f
&X::a
不是 指针。因为
f
a
都是 非静态 成员,所以它们是 成员指针,无论命名和语法相似性如何,它们的行为都与 指针 非常不同。

成员指针(无论是函数还是数据成员)并不代表地址。所以尝试打印它的地址是没有意义的。

因此,标准库中的

<<
std::ostream
也没有重载,这也需要成员指针。

但是,存在以

bool
作为参数的重载,并且可以将成员指针隐式转换为
bool
。如果成员指针具有空成员指针值,则结果为
false
,否则结果为
true
。使用默认设置
true
将打印为
1


1
投票

表达式

&X::a
不是可以在普通地址中使用的地址。它是成员的相对地址。它只能与指向成员的指针一起使用。

指向成员的指针可以转换为其他指向成员的指针,并且仅在有约束的情况下。它们不能转换为其他类型的指针或 int。在这种情况下很难打印它们的值。

唯一可能的转换是布尔值,它的目的是查看它是否为空。因为指向成员的指针可以为 nullptr:

int X::*px = &X::a;
bool bx = px; std::cout << bx <<std::endl; 
px = nullptr; 
bool bn = px; std::cout << bn <<std::endl; 

如果要打印指向成员的指针的地址,则必须使用对象取消引用它:

std::cout << std::hex << &(xobj.*(&X::a)) << std::endl; 

正如您可能想象的那样,不可能使用取消引用 nullptr 来成员或使用 nullptr 作为对象地址的技巧,因为取消引用空指针是 UB。顺便说一句,这不是一个真正的问题,因为该标准对对象的布局几乎没有保证,因此这个相对地址本身没什么用处。

© www.soinside.com 2019 - 2024. All rights reserved.