【问题标题】:Using declaration and multiple inheritance使用声明和多重继承
【发布时间】:2021-07-07 18:52:54
【问题描述】:

我们知道,在其中定义了另一个同名实体的范围内,命名空间成员名称的“使用声明”会导致编译时错误:“符号 x 已定义”。

在“使用声明”出现的点检测到错误,而不是像“使用指令”那样出现在使用点。

类范围内的 using 声明只允许公开基类成员名称。

这是一个例子:

#include <iostream>
using namespace std;

struct Foo{
    Foo(int x) : x_(x){}
    int x_ = 0;
};

struct Bar{
    Bar(int y) : y_(y){}
    int y_ = 0;
};

struct FooBar : Foo, Bar{
    using Foo::Foo; // inheriting Foo's ctors
    using Bar::Bar; // inheriting Bar's ctors

    int x_ = 10;
//    using Foo::x_; // error detected here
};

int main(){
    FooBar fb(5); // error detected here

}

正如您在上面看到的,Foo::x_ 的 using 声明会在 using 出现时导致编译时错误,这没关系。

但是基类 Foo 和 Bar 构造函数的 using 声明直到 main 中的使用才发出错误?!!

  • 通常 FooBar 继承 Foo(int);因此,当using Bar::Bar; 正常出现时,编译器会抱怨,但代码工作正常,直到我尝试使用该构造函数。 FooBar(int)。

在继承了所有的构造函数之后,编译器定义了一个派生类ctor,并让它调用它的基类,将它的参数传递给它,就像我们这样写:

struct FooBar : Foo, Bar{
        FooBar(int x) : Foo(x){}
        FooBar(int x) : Bar(x){}
//...
};

那么为什么编译器允许这样的错误呢?并等到使用该 ctor 来标记歧义??

  • 在我看来,这种情况下的 using 声明与 using 指令的作用相同。

【问题讨论】:

  • 您说“基类 Foo 和 Bar 构造函数的 using 声明在 main 中使用之前不会发出错误?!!”好吧,它们会导致错误,请注释以下两行 FooBar fb(5);和 int x_ = 10;您将在使用 Bar::Bar; 时获得已经从 foo 继承的 bar 构造函数
  • 不,这就是我发布这个问题的原因。
  • 不是吗?你的意思是,当你评论这两行时,你没有得到错误??如果你没有收到错误,那一定是编译器设置
  • @ma1169:是的,当然。我已经说过了。我正在使用 gcc 和 clang。

标签: c++ gcc constructor multiple-inheritance using-declaration


【解决方案1】:

C++ 的一个一般(虽然不是通用)原则是,当且仅当有 some 有效的完成使用它时,程序的 前缀 才有效前缀中的声明。这就是为什么声明一个未使用的变量不是错误的原因:它可以被使用,如果不是,那么以后拒绝它就“为时已晚”。在这里,这个原则被概括了一点,因为重载解析通常可以区分来自不同命名空间或基类的函数,根本不检查冲突。

变量并非如此,因为您不可能使用模棱两可的组合。如果其中一个冲突的函数声明是 direct 成员和 using-declaration 的兄弟,则也不是这样:在这种情况下,您可能无法使用您的函数声明,所以你被认为不是故意的。

【讨论】:

    猜你喜欢
    • 2016-07-20
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2019-07-16
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多