如何重写另一个基类中的函数?

2023-11-24

我不太确定要使用的术语,但这是我的示例:

class Base {
public:
    virtual void test() = 0;
};

class Mixin {
public:
    virtual void test() { }
};

class Example : public Base, public Mixin {
};

int main(int argc, char** argv) {
    Example example;
    example.test();
    return 0;
}

我想要我的Mixin实现纯虚函数的类Base::test,但是当我编译它时,它说:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:15:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^
test.cpp:16:13: error: request for member ‘test’ is ambiguous
     example.test();
             ^
test.cpp:8:18: note: candidates are: virtual void Mixin::test()
     virtual void test() { }
                  ^
test.cpp:3:18: note:                 virtual void Base::test()
     virtual void test() = 0;
                  ^

我可以添加一个using声明使其不含糊:

class Example : public Base, public Mixin {
public:
    using Mixin::test;
};

但它说我还没有实现它:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:17:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^

是否有可能做到这一点?

我知道一种选择是Mixin继承自Base,但就我而言,有几个派生类,并且它们不具有共同的祖先。


你不能directly让一个类重写不属于其基类的方法。但你可以用一种迂回的方式来做到这一点。我将介绍两种这样的方法 - 我更喜欢第二种。

方法一

丹尼尔·保罗 (Daniel Paul) 在一篇文章中对此进行了描述thinkbottomup.com.au,题为C++ Mixins - 通过继承重用是很好的......如果以正确的方式完成.

在你的情况下,它看起来像这样:

class Base {
public:
    virtual void test() = 0;
};

template <typename T>
class Mixin : public T {
public:
    virtual void test() override { /*... do stuff ... */ }
};

class UnmixedExample : public Base {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};

using Example = class Mixin<UnmixedExample>;

int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}

方法二:CRTP!

CRTP是“奇怪的重复模板模式” - 如果您以前没有见过它,请务必点击该链接。通过这种方法,我们将使用virtual继承说明符以避免歧义,并且与以前的方法不同 - 我们不会颠倒继承顺序Mixin and Example类。

class Base {
public:
    virtual void test() = 0;
};

template <typename T>
class Mixin : virtual T {
public:
    virtual void test() override { /*... do stuff ... */ }
};

class Example : public virtual Base, public virtual Mixin<Base> {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};

int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}

关于这两种解决方案的注意事项:

  • 难道不奇怪 CRTP 为何不断在各处重复出现吗? :-)
  • 出于教学目的,我使用的代码是 C++11,但在 C++98 中也可以使用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何重写另一个基类中的函数? 的相关文章

随机推荐

  • AVAudioPlayer初始化错误

    我初始化我的 AVAudioPlayer 实例 如下所示 self audioPlayer initWithContentsOfURL url error err url 包含 m4a 文件的路径 调用此行时 控制台中会显示以下错误 错误域
  • 无头/CLI LibGDX

    我正在为一个小型 LibGDX 支持的游戏编写服务器端代码 并且偶然发现了一个问题 每次我尝试使用任何Gdx files 方法 我遇到了NullPointerException 显然这是因为我没有实现 ApplicationListener
  • 如何让服务在睡眠模式下也能运行?

    我有正在实现位置侦听器的服务 现在我的问题是如何确保我的服务即使在睡眠模式下也能捕获位置 我读过有关警报管理器的内容 alarm setRepeating AlarmManager RTC WAKEUP triggerAtMillis in
  • 如何指定 ASP.NET Web API 中需要 JSON 还是 XML?

    本周我编写了两个 ASP NET Web API 应用程序 它们都包含一个简单的控制器 我已经对每一个进行了调整 以使它们能够工作 包括异常等等 但据我所知 它们的配置几乎相同 其中一个返回 JSON 另一个返回 XML 我希望他们都返回
  • 与 pyodbc 的通信链路失败

    import pyodbc import time connection pyodbc connect cursor connection cursor while True time sleep 1 cursor execute INSE
  • Python的Multiprocessing的进程通信

    我了解了Python多进程的Pipes Queues Shared ctypes Objects Managers 我想将它们与Linux的匿名管道 命名管道 共享内存 套接字等进行比较 我现在有以下问题 Python 多处理的管道和队列模
  • 使用 R 并行化抓取网页

    我正在尝试抓取大量网页以便稍后分析它们 由于 URL 数量巨大 我决定使用parallel包装连同XML 具体来说 我正在使用htmlParse 函数来自XML 与使用时效果很好sapply 但与使用时会生成 HTMLInternalDoc
  • 支持工具栏的自定义视图不使用全宽

    我正在使用 support v7 的工具栏 我添加了自定义视图 但自定义视图似乎不遵守 match parent 它只会延伸到它看到的第一个图标 有谁知道解决这个问题吗 或者工具栏不应该这样使用 我的代码
  • 使用 POEdit——仅搜索特定域中的字符串

    我创建了一个想要翻译的 WordPress 主题 在我的主题中 我使用了一些翻译woocommerce i e 这些 woocommerce 字符串 我自然不想再次翻译 因为它们已经被翻译了 但是当我使用 poedit 扫描我的主题时 它当
  • java.sql.SQLException:I/O 错误:SSO 失败:本机 SSPI 库

    我有两个网络应用程序需要在 Tomcat 6 MS SQL 2008 和 JTDS 1 2 2 作为驱动程序上运行 如果我只启动一个 Web 应用程序 一切都工作正常 但是一旦我启动第二个应用程序 我就会收到以下错误 顺序无关紧要 java
  • 获得Facebook的读取权限后获得publish_action权限

    我正在整合Facebook登录我的应用程序 我能够获得读取权限 但如何从 Facebook SDK 获得发布权限 这就是我请求读取权限的方式 Override public void onClick View v Session curre
  • 如何让 addEventListener 与 select 标签一起使用

    HTML
  • event.preventDefault() 不适用于 android chrome

    event preventDefault 不适用于 Chrome Android 操作系统 而同样的操作也适用于 chrome IOS 我什至使用了 event stopPropagation event stopImmediateProp
  • Spring-Boot 多模块无法从另一个模块读取属性文件

    我搜索了高低 但仍然无法找到这个非常烦人的问题的简单答案 我遵循了这个伟大的指南 JWT 与多服务应用程序一切都很好 但在指南的最后 建议我们创建一个 config service module 我已经完成了 问题是我无法覆盖 JwtCon
  • 在 ICS 或 JB 上的任务管理器中显示自定义应用程序映像

    据我所知 在 Android 4 0 或更高版本 上 默认任务管理器显示程序的最后一个屏幕截图 程序图标没有左上角 看图片 我的问题是如何将任务管理器中的应用程序图像 不是图标 更改为自定义 别问我为什么 我只是需要 经过一番研究 我发现了
  • sed 中的“0,/xxx”是什么意思?

    脚本中使用的 sed 命令如下 sed i 0 ENABLE DEBUG s ENABLE DEBUG ENABLE DEBUG YES MakeConfig 我知道 s ENABLE DEBUG ENABLE DEBUG YES 是替换行
  • R:输出带有小计的类似数据透视表

    我正在尝试在 R 中进行交叉制表 并使其输出尽可能类似于 Excel 数据透视表中的输出 目标是用 R Markdown 自动生成的报告取代使用 Excel 和 Word 手动生成的报告 数据整理和图表已经处理完毕 但缺少一些表格 所以 给
  • 有没有比这更好的方法从 PrintDocument 获取页数?

    这是我想出的最好的 public static int GetPageCount PrintDocument printDocument printDocument PrinterSettings PrintFileName Path Ge
  • WebView不会播放任何声音

    我使用最简单的 WebView 实例 到目前为止 所需的一切都运行良好 除了播放声音之外 javascript 调用的声音和 html5 音频标签都无法通过此 WebView 工作 public class MainActivity ext
  • 如何重写另一个基类中的函数?

    我不太确定要使用的术语 但这是我的示例 class Base public virtual void test 0 class Mixin public virtual void test class Example public Base