当前位置: 首页 > 知识库问答 >
问题:

强制派生类重写一组虚函数之一

吕利
2023-03-14

给定一个具有一些虚函数的基类,有人能想出一种方法来强制派生类在编译时重写一组虚函数中的一个吗?或者是实现相同目标的类层次结构的另一种提法?

代码中:

struct Base
{
    // Some imaginary syntax to indicate the following are a "pure override set"
    // [
    virtual void function1(int) = 0;
    virtual void function2(float) = 0;
    // ...
    // ]
};

struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Base { void function1(int) override; }; // OK
struct Derived3 : Base { void function2(float) override; }; // OK

struct Derived4 : Base // ERROR too many implemented
{
    void function1(int) override;
    void function2(float) override;
};

我不确定我真的有一个实际的用例,但是当我实现一些松散地遵循这个模式的东西时,我想到了这个问题,并且认为这是一个有趣的问题,需要思考。

共有2个答案

邢新
2023-03-14

如果不重写所有抽象的虚拟方法,您的类将保持抽象。如果要实例化对象,您必须执行所有这些操作。

班宏毅
2023-03-14

不,但你可以假装。

Base具有非虚拟的float和int方法,这些方法转发到纯虚拟的std变体。

两个助手类,一个int一个float,实现了std变体1,将这两种情况转发给纯虚拟int或float实现。

它负责处理“错误类型”案件。

从一个或另一个helper派生inherit,并仅实现int或float。

struct Base
{
    void function1(int x) { vfunction(x); }
    void function2(float x) { vfunction(x); }
    virtual void vfunction(std::variant<int,float>) = 0;
};
struct Helper1:Base {
    void vfunction(std::variant<int,float> v) final {
      if (std::holds_alternative<int>(v))
        function1_impl( std::get<int>(v) );
    }
    virtual void function1_impl(int x) = 0;
};
struct Helper2:Base {
    void vfunction(std::variant<int,float> v) final {
      if (std::holds_alternative<float>(v))
        function2_impl( std::get<float>(v) );
    }
    virtual void function2_impl(float x) = 0;
};

struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Helper1 { void function1_impl(int) override; }; // OK
struct Derived3 : Helper2 { void function2_impl(float) override; }; // OK

这使用https://en.wikipedia.org/wiki/non-virtual_interface_pattern--接口包含非虚拟方法,可以重写这些方法的详细信息以使它们的行为不同。

如果您担心人们会重写vfunction,您可以使用私有锁技术,或者只给它起一个类似private_implementation_detail_do_not_implement的名字,并信任您的代码审查过程。

 类似资料:
  • 当派生类不是立即派生,而是从已经派生的类派生时,我对覆盖函数感到困惑。 在这两种情况下,都调用了最派生的析构函数。我想知道是否只需要大多数基类有一个声明为虚拟的析构函数,在这种情况下,从它继承的所有其他类都有虚拟析构函数,覆盖上游的所有其他析构函数,如果你明白我的意思的话。 我不确定我是否有意义,基本上,如果我有一系列10个类,每个类都从上一个继承,那么链中的任何析构函数都会覆盖所有比它更基础的析

  • 其实,类似的问题这里问过,那里问过,但回答都不满意。代码示例是 输出为 关于 由于是虚函数,派生类不实现它,因此程序将调用; 则程序将调用; 是一个常规函数,程序将调用; 也是一个常规函数,程序将调用; 我不明白的部分来了,不是虚函数,是属于的指针,基本上只能访问中的函数!但输出是 相比之下,会像我想的那样调用。 在基类指针只能访问基类和虚函数中定义的函数的原则与实际输出之间似乎存在矛盾。原因也无

  • 我正在学习面向对象的C,并有一个关于虚拟/纯虚拟和多级继承的问题。 假设我有这样的简单代码: 我的理解是,除非getWidth被指定为虚拟,否则多态将使用“Base”类的函数。我的意思是r-的最终调用 在这种情况下,我注意到如果我删除Shape中的纯虚拟声明,我们会得到我刚才描述的行为。在基类中有一个纯虚函数会自动使该函数的所有定义都是虚的吗?

  • C核心指南包含以下关于、和说明符的建议,特别是与派生类析构函数相关的建议: 如果基类析构函数声明为虚拟,则应避免将派生类析构函数声明为虚拟或重写。某些代码库和工具可能会坚持重写析构函数,但这不是这些准则的建议。 果然,是违反建议的工具之一。如果我没有指定或,运行会发出以下警告: 或者,如果仅指定为: 特别是,指定<code>override</code>的优点是(至少)确保正确地将基类析构函数指定

  • 为什么一个虚函数在派生类中默认是虚的,甚至不可能在派生类中完全移除虚性,这有什么好的理由吗? 我希望这种行为的原因与我不希望默认情况下每个函数都是的原因相同。编译器可能会生成牺牲性能的vtables。 基类应该有一个vtable(我想要多态性在那里),但派生类没有vtable(我不希望多态性在那里,为什么我要那样,只是因为它派生了一个具有多态性的类?)。 我想解决的问题是更好地理解虚函数。我只是没

  • 我在嵌入式环境中使用 C,其中虚拟函数的运行时确实很重要。我读过关于可以内联虚拟函数的罕见情况,例如:内联虚函数真的是无意义的吗?接受的答案指出,只有在运行时已知确切的类时,例如在处理本地、全局或静态对象(不是指针或对基类型的引用)时,才有可能进行内联。我理解这背后的逻辑,但我想知道在以下情况下是否也可以内联: 从我的观点来看,编译器应该在编译时知道的最终类型,因为它是一个最终类。在这种情况下,是