JBL*_*JBL 4 c++ overriding virtual-functions using-declaration private-inheritance
让我们考虑两个类,A并B使用以下接口:
class A {
public:
virtual void start() {} //default implementation does nothing
};
class B {
public:
void start() {/*do some stuff*/}
};
Run Code Online (Sandbox Code Playgroud)
然后是A公开的第三个类,它是公开的,因为它实现了这个"接口",B私下因为它的实现细节.
但是,在此特定实现中,start()只需要包含一个调用B::start().所以我想我可以使用快捷方式并执行以下操作:
class C: public A, private B {
public:
using B::start;
};
Run Code Online (Sandbox Code Playgroud)
并完成它,但显然它不起作用.所以我得using私有基本功能不起作用,以覆盖虚拟.由此,有两个问题:
start()函数具有完全相同的签名C,但编译器看起来很好,只有调用A::start().编辑:一些准确性:
C通过A指针操纵对象.B::start(),我特别想知道一个using声明是否确实可以"覆盖"一个虚拟,如果没有,这是如何允许这两个函数共存的.virtual为简单起见,我可能省略了一些像继承这样的东西.是否有任何方法可以使这项工作,因为我认为它可能有效?
你应该覆盖成员函数并显式调用B::start():
class C: public A, private B {
public:
void start() override { B::start(); }
};
Run Code Online (Sandbox Code Playgroud)
为什么编译器会接受此代码有效?正如我所看到的,现在有两个
start()函数在C中具有完全相同的签名,但编译器看起来很好并且只能调用A::start().
你是对的,有两个成员函数可以在C(A::start()和B::start())中访问.并且,在class C没有通过执行a 覆盖start()或使start()任何基类可见的情况下using ...::start(),当尝试使用来自对象的未经验证的namelookup调用成员函数时,将会出现歧义错误C.
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Error, ambiguous
}
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您必须使用限定名称,例如:
C* c = new C();
c->A::start(); //Ok, calls A::start()
Run Code Online (Sandbox Code Playgroud)
现在,做一个using B::start()在class C简单的声明start()指B::start(),每当这样的名称是从对象使用C
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
using B::start();
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Ok, calls B::start()
}
Run Code Online (Sandbox Code Playgroud)
using B::start使函数void B::start()可见C,它不会覆盖它.要调用make所有上述不合格的成员函数调用,要调用B::start(),你应该覆盖成员函数C,然后调用它B::start()
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
void start() override { B::start(); }
};
int main(){
A* a = new C();
a->start(); //Ok, calls C::start() which in turn calls B::start()
// ^^^^^^^^^^^^^^^^ - by virtual dispatch
C* c = new C();
c->start(); //Ok, calls C::start() which in turn calls B::start()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |