C++ 语法“A::B:A ;”是啥意思?意思是

Posted

技术标签:

【中文标题】C++ 语法“A::B:A ;”是啥意思?意思是【英文标题】:What does C++ syntax “A::B:A ;” meanC++ 语法“A::B:A ;”是什么意思?意思是 【发布时间】:2018-05-12 19:09:09 【问题描述】:

C++ 语法struct A::B:A ; 是什么意思? C++ 标准中描述的名称定义(或访问)在哪里?

#include <iostream>

struct B;

struct A 
    struct B;
;

struct A::B:A 
;

int main() 
    A::B::A::B b;
    std::cout<<"Sizeof A::B::A::B is " << sizeof(A::B::A::B)<<std::endl;
    return 0;

【问题讨论】:

不需要首字母struct B;。它不在代码中的任何地方使用。 @AnT 只是在这个翻译单元中没有使用它。但就这个例子而言,我认为没有其他翻译单元,并且很有可能操作可能有认为这是必须的。 @sjsam:即使B在另一个翻译单元中使用,在这个TU中声明仍然是多余的。 命名空间 A 中的内部 B 作为 A 的子节点 【参考方案1】:

这个定义

struct A 
    struct B;
;

使用嵌套结构 B1 的声明定义结构 AB 的完全限定名称是 A::B,您可以说 BA 的“命名空间”内。那么这个:

struct A::B : A  // Note I added spaces
;

A::B的定义,单个:指定它派生A

现在,有趣的部分是A::B::A::B。让我们剖析一下:

    A::B 命名嵌套结构。 A::B::A 访问B 内注入的类名A。注入是由于继承。 A::B::A::BA 中再次命名嵌套结构 B

您可以无限继续,或者至少直到您的编译器达到其翻译限制2

一个有趣的智力练习,但避免像实际代码中的瘟疫一样。


[class.qual]/1 解释了查找的工作原理

如果 qualified-idnested-name-specifier 指定了一个类,则 在 nested-name-specifier 之后指定的名称在 类的范围([class.member.lookup]),除了情况 下面列出。该名称应代表该组织的一个或多个成员 类或其基类之一(子句 [class.derived])。

上面的文字允许我们命名基类,因为[class]/2

class-name 也被插入到类本身的作用域中; 这被称为 injected-class-name。出于访问目的 检查,injected-class-name 被视为公共的 会员名。

上面清楚地表明,以A:: 开头的完全限定名称允许您指定成员或基类。由于A 没有基数,您只能指定A::B(“成员类型”)。但是A::B 也提名了一个班级。所以我们可以用A::B:: 指定that 的基数或成员,这样我们就可以命名A::B::A。现在冲洗并重复。


1 - 注意它完全是另一个B。与全局 struct B 完全无关。2 - 根据 [implimits]/2.36 建议的最小值为 256

【讨论】:

如果替换 std::cout 会发生什么 @devsh - 你并没有真正进行递归。您只需回溯并选择两种类型中的一种。无论您重复多少次,该表达式中只有两种类型。所以sizeof( A::B::A::B::A::B::A::B::A::B)sizeof(A::B) 没有什么不同 @devsh - 等等。我将添加一个标准报价。我们会看看它是否会为您解决问题。 @devsh - 在那里。这就是报价。请注意它是如何表示如果“前缀”命名一个类如何 类被命名并不重要。我们命名它,我们可以再次使用:: 来访问其中的某些内容。 对新编码员的注意A::B::A::B::A::B 可能会让你陷入困境,或者充其量是被画成四等分。命名很难,但并不难:-)【参考方案2】:

首先struct B; 是结构B 在全局命名空间中的前向声明。这可能会令人困惑,因为它实际上与此示例无关。这个全局B 可以作为::BB 访问。

struct A 
    struct B;
;

是在全局命名空间中定义 struct A,并带有 nested struct B 的前向声明(与之前在全局命名空间中声明的 B 不同)。这个嵌套的B 可以通过::A::BA::B 访问。

struct A::B:A 
;

是从A 继承的结构A 的嵌套结构B 的定义(省略了访问说明符)。可以改写为:

struct A::B
:   public A

;

请注意,像这样在 A 定义中编写嵌套结构 B 的定义是行不通的:

struct A 
    struct B: A  // error: A is incomplete at this point
    ;
;

最后A::B::A指的是嵌套结构B的基类,即A,所以A::B::A::B就相当于A::B

【讨论】:

澄清一下(我自己和其他想知道的人)——struct 的默认继承访问修饰符是public,而不是classprivate? (因此说: public A 是等价的) @QPaysTaxes 是的,struct 的默认访问修饰符是 public,它适用于字段、方法、嵌套类型和基类。请注意,这有助于保持与 C 的向后兼容性,否则 C 结构的所有字段都将无法访问。 @devsh A::B::A::B::A::B::A::B::A::B 不是递归继承。它只是一个嵌套类型访问链,仍然等同于A::B。另请注意,递归继承在 C++ 中是不可能的,因为在某些时候,继承链中的一种类型会不完整。并且给定的代码不包含递归继承。 @devsh 也可以让这个链在没有任何继承的情况下工作:struct B; struct A using B = ::B; ; struct Busing A = ::A; ; @devsh 因为A::B::A 仅相当于A。您可以通过写static_assert(::std::is_same_v&lt;A, A::B::A&gt;); 来验证这一点。所以这条链可以从左到右简化为A::B::A::B::A::B::A::B 然后A::B::A::B::A::B 然后A::B::A::B 然后A::B

以上是关于C++ 语法“A::B:A ;”是啥意思?意思是的主要内容,如果未能解决你的问题,请参考以下文章

js中value^= 是啥意思

c++ 隐式声明是啥意思

Java语言,括号里的字符串"a="+a+" b"+b是啥意思呢?:

c语言里的一等公民是啥意思

双冒号是啥意思?

逻辑运算 ⊙ & 小圆圈里一个加号 是啥意思