gpt4 book ai didi

c++ - 用私有(private)基函数覆盖公共(public)虚函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:31 25 4
gpt4 key购买 nike

让我们考虑具有以下接口(interface)的两个类 AB:

class A {
public:
virtual void start() {} //default implementation does nothing
};

class B {
public:
void start() {/*do some stuff*/}
};

然后是从两者继承的第三个类,A 是公开的,因为它实现了这个“接口(interface)”,B 是私有(private)的,因为那是实现细节。

但是,在这个特定的实现中,start() 只需要包含对 B::start() 的调用。所以我想我可以使用快捷方式并执行以下操作:

class C: public A, private B {
public:
using B::start;
};

并完成它,但显然它不起作用。所以我得到 using private base function doesn't work to override virtuals。由此,有两个问题:

  • 有什么方法可以使它像我认为的那样工作吗?
  • 为什么编译器会接受这段代码有效?正如我所见,现在有两个 start() 函数在 C 中具有完全相同的签名,但编译器似乎没有问题,只调用 A::开始()

编辑:一些精确度:

  • 目标是通过A指针操作C对象。
  • 我目前正在使用一个简单的函数,它只调用 B::start(),我特别想知道 using 声明是否确实可以“覆盖”一个虚拟的,如果不能,这是如何实现的允许两种功能共存。
  • 为了简单起见,我可能省略了一些东西,例如 virtual 继承。

最佳答案

Is there any way to make this work as I supposed it may have worked?

您应该覆盖成员函数并显式调用 B::start():

class C: public A, private B {
public:
void start() override { B::start(); }
};

Why would the compiler accept this code as valid? As I see it there are now two start() functions with the exact same signature in C and yet the compiler seems fine with it and only calls A::start().

您是对的,在 C 中有两个可访问的成员函数(A::start()B::start())。在 class C 中,无需覆盖 start() 或通过执行 使任何基类的 start() 可见使用 ...::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 {
};

int main(){
A* a = new C();
a->start(); //Ok, calls A::start()

C* c = new C();
c->start(); //Error, ambiguous
}

要解决这个问题,您必须使用限定名称,例如:

    C* c = new C();
c->A::start(); //Ok, calls A::start()

现在,在 class C 中使用 using B::start() 简单地声明 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()
}

使用 B::start 使函数 void B::start()C 中可见,它不会覆盖它。调用make上述所有不合格的成员函数调用,调用B::start(),你应该覆盖C中的成员函数,让它调用 B::开始()

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()

}

关于c++ - 用私有(private)基函数覆盖公共(public)虚函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41808357/

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