gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 14:03:01 27 4
gpt4 key购买 nike

在更大的代码库中,我遇到过这样的代码( see on godbolt ):

struct Foo {};

struct Base {
Foo* a;
};

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

Foo* Bar::Bar::*mybar[] = {
&Base::a
};

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

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

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

最佳答案

首先, Bar::mybar 是一个 pointers to members 数组。这些不是实际的指针。它们更像是对对象偏移量的抽象。它们允许间接访问成员。给定一个 Base 对象(或从它派生的对象),我们可以调用它们,如下所示

aBar.*mybar[0] // This resolve to a Foo* inside aBar

另一件值得注意的事情是,在您的示例中, namespace 范围内的对象不是 Bar::mybar 的定义。这是一个不相关的数组。正确的定义是
Foo* Bar::* Bar::mybar[] = {
&Base::a
};

这是因为您的定义错误,删除某些限定名称没有效果。当你删除它时,你只剩下
static Foo *mybar[];

Foo Bar::*mybar[] = {
&Base::a
};

声明和“定义”的类型不匹配。但是你没有错误,因为它们实际上是不同的对象。

在正确的定义中,每个 Bar:: 限定符都是必需的,用于不同的目的。一个用于创建正确的类型(指向 Bar 成员的指针),另一个指定正在定义的 Bar 的静态成员,并且在每个静态类成员定义中都需要。

关于c++ - (为什么)我们可以在初始化时将非静态类成员分配给静态变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62156981/

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