(为什么)我们可以在初始化时将非静态类成员分配给静态变量吗?

and*_*eee 4 c++ inheritance static class c++11

在更大的代码库中,我遇到过这样的代码(参见 Godbolt):

struct Foo {};

struct Base {
    Foo* a;
};

struct Bar : public Base {
    static Foo* Bar::*mybar[];
};

Foo* Bar::Bar::*mybar[] = {
    &Base::a
};
Run Code Online (Sandbox Code Playgroud)

老实说,我很困惑。这看起来像是在初始化一个静态Foo指针数组,Bar其中包含一个非静态成员变量Base。没有对象怎么可能呢?

(免责声明:这是在实际工作的生产代码中发现的 - 希望不依赖于 UB?)

另外,如果我删除像这里这样的限定名称查找有什么问题吗?我想重构代码并使其更具可读性。所有这些Bar::似乎都是多余的,但由于我对代码感觉不太舒服,我宁愿先了解其含义。

Nat*_*ica 8

与普通指针不同,类成员指针可以被认为是类的偏移量,它们告诉您它们指向对象的哪个成员。所以在你的代码中,mybar是一个类成员指针数组。当你做

Foo *Bar::Bar::*mybar[] = {
    &Base::a
};
Run Code Online (Sandbox Code Playgroud)

你用一个指向 的a成员的指针来初始化数组Base。这实际上并不是指向 an a,它只是告诉编译器,如果您使用对象访问它,要返回该对象的哪个成员。那看起来像

Base foo; // now we have an actual object
foo.*mybar[0]; // access the `a` member of `foo` by using the "offset"
Run Code Online (Sandbox Code Playgroud)