'using' 从多个虚拟继承函数中选择的关键字
'using' keyword to choose from multiple virtual inherited functions
我有一个 class ('TestC'),它派生自另外两个 classes('TestA' 和 'TestB'),这两个有一个具有相同签名的虚函数。
为了让函数可以通过 'TestC' 访问,我必须告诉它使用哪个版本。如果我显式覆盖 'TestC' 中的函数并调用我想要的版本,这将起作用:
#include <iostream>
class TestA
{
public:
virtual void test() {std::cout<<"a";}
};
class TestB
{
public:
virtual void test() {std::cout<<"b";}
};
class TestC
: public TestA,public TestB
{
public:
void test() {TestB::test();}
};
int main(int argc,char *argv[])
{
TestC c;
TestA *a = static_cast<TestA*>(&c);
a->test();
c.test();
for(;;);
return EXIT_SUCCESS;
}
输出:"bb"
这是预期的结果。但是,我注意到如果我使用 'using' 关键字,而不是显式地覆盖函数,我会得到一些意想不到的行为:
class TestC
: public TestA,public TestB
{
public:
using TestB::test;
};
(其他同理)
输出:"ab"
谁能给我解释一下?好像 'test' 突然不虚拟了?有没有办法做到这一点,而无需明确覆盖该功能? (类似于 "using override")
使用 using
,您不定义 TestC::test()
,而是告诉 TestB::test()
可见(因此隐藏 TestA::test()
,这使得 c.test()
不可见模棱两可)。
using 声明永远不会覆盖虚函数。但是,它可以消除多重继承的歧义。在示例中 a->test()
调用:
- TestC 的覆盖(调用 TestB::f)
- TestB的覆盖(TestC没有覆盖)
以下(菱形)虚拟继承中的 using 声明未提供所需的最终覆盖:
struct Base {
virtual void f();
};
struct A : virtual Base {
virtual void f() override {}
};
struct B : virtual Base {
virtual void f() override {}
};
struct Derived : A, B {
// error: no unique final overrider for ‘virtual void Base::f()’ in ‘Derived’
using A::f;
};
更多示例:
#include <iostream>
// Single Inheritance
// ==================
namespace Single {
struct A {
virtual void f() { std::cout<<"A\n"; }
};
struct AA : A {
virtual void f() override { std::cout<<"AA\n"; }
};
struct Derived : AA {
// Has no impact if not called explicitly
using A::f;
};
} // namspace
// Multiple Inheritance
// ====================
namespace Multiple {
struct A {
virtual void f() { std::cout<<"A\n"; }
};
struct AA : A {
virtual void f() override { std::cout<<"AA\n"; }
};
struct B {
virtual void f() { std::cout<<"B\n"; }
};
struct BB : B {
virtual void f() override { std::cout<<"BB\n"; }
};
struct Derived : AA, BB {
// Disambiguate A::f (AA::f) and B::f (BB::f)
using A::f;
};
} // namspace
// Test
// ====
int main() {
std::cout << "Single\n";
{
Single::Derived d;
d.f(); // calls AA::f
d.Derived::f(); // calls A::f because of the using-declaration
}
std::cout << "Multiple\n";
{
Multiple::Derived d;
d.f(); // calls AA::f
d.Derived::f(); // calls A::f because of the using-declaration
}
}
注意:我在标准草案N4296中没有找到任何确凿的解释。
我有一个 class ('TestC'),它派生自另外两个 classes('TestA' 和 'TestB'),这两个有一个具有相同签名的虚函数。
为了让函数可以通过 'TestC' 访问,我必须告诉它使用哪个版本。如果我显式覆盖 'TestC' 中的函数并调用我想要的版本,这将起作用:
#include <iostream>
class TestA
{
public:
virtual void test() {std::cout<<"a";}
};
class TestB
{
public:
virtual void test() {std::cout<<"b";}
};
class TestC
: public TestA,public TestB
{
public:
void test() {TestB::test();}
};
int main(int argc,char *argv[])
{
TestC c;
TestA *a = static_cast<TestA*>(&c);
a->test();
c.test();
for(;;);
return EXIT_SUCCESS;
}
输出:"bb"
这是预期的结果。但是,我注意到如果我使用 'using' 关键字,而不是显式地覆盖函数,我会得到一些意想不到的行为:
class TestC
: public TestA,public TestB
{
public:
using TestB::test;
};
(其他同理)
输出:"ab"
谁能给我解释一下?好像 'test' 突然不虚拟了?有没有办法做到这一点,而无需明确覆盖该功能? (类似于 "using override")
使用 using
,您不定义 TestC::test()
,而是告诉 TestB::test()
可见(因此隐藏 TestA::test()
,这使得 c.test()
不可见模棱两可)。
using 声明永远不会覆盖虚函数。但是,它可以消除多重继承的歧义。在示例中 a->test()
调用:
- TestC 的覆盖(调用 TestB::f)
- TestB的覆盖(TestC没有覆盖)
以下(菱形)虚拟继承中的 using 声明未提供所需的最终覆盖:
struct Base {
virtual void f();
};
struct A : virtual Base {
virtual void f() override {}
};
struct B : virtual Base {
virtual void f() override {}
};
struct Derived : A, B {
// error: no unique final overrider for ‘virtual void Base::f()’ in ‘Derived’
using A::f;
};
更多示例:
#include <iostream>
// Single Inheritance
// ==================
namespace Single {
struct A {
virtual void f() { std::cout<<"A\n"; }
};
struct AA : A {
virtual void f() override { std::cout<<"AA\n"; }
};
struct Derived : AA {
// Has no impact if not called explicitly
using A::f;
};
} // namspace
// Multiple Inheritance
// ====================
namespace Multiple {
struct A {
virtual void f() { std::cout<<"A\n"; }
};
struct AA : A {
virtual void f() override { std::cout<<"AA\n"; }
};
struct B {
virtual void f() { std::cout<<"B\n"; }
};
struct BB : B {
virtual void f() override { std::cout<<"BB\n"; }
};
struct Derived : AA, BB {
// Disambiguate A::f (AA::f) and B::f (BB::f)
using A::f;
};
} // namspace
// Test
// ====
int main() {
std::cout << "Single\n";
{
Single::Derived d;
d.f(); // calls AA::f
d.Derived::f(); // calls A::f because of the using-declaration
}
std::cout << "Multiple\n";
{
Multiple::Derived d;
d.f(); // calls AA::f
d.Derived::f(); // calls A::f because of the using-declaration
}
}
注意:我在标准草案N4296中没有找到任何确凿的解释。