C++中接口的多重继承

2024-01-07

我有一个对象接口和派生对象可能想要支持的开放式接口集合。

// An object
class IObject
{
    getAttribute() = 0
}

// A mutable object
class IMutable
{
    setAttribute() = 0
}

// A lockable object 
class ILockable
{
    lock() = 0
}

// A certifiable object 
class ICertifiable
{
    setCertification() = 0
    getCertification() = 0
}

一些派生对象可能如下所示:

class Object1 : public IObject, public IMutable, public ILockable {}
class Object2 : public IObject, public ILockable, public ICertifiable {}
class Object3 : public IObject {}

这是我的问题:有没有一种方法可以编写只采用这些接口的某些组合的函数?例如:

void doSomething(magic_interface_combiner<IObject, IMutable, ILockable> object);

doSomething( Object1() )  // OK, all interfaces are available.
doSomething( Object2() )  // Compilation Failure, missing IMutable.
doSomething( Object3() )  // Compilation Failure, missing IMutable and ILockable.

我发现的最接近的是 boost::mpl::inherit。我取得了一些有限的成功,但它并没有完全满足我的需要。

例如:

class Object1 : public boost::mpl::inherit<IObject, IMutable, ILockable>::type
class Object2 : public boost::mpl::inherit<IObject, ILockable, ICertifiable>::type
class Object3 : public IObject

void doSomething(boost::mpl::inherit<IObject, ILockable>::type object);

doSomething( Object1() )  // Fails even though Object1 derives from IObject and ILockable.
doSomething( Object2() )  // Fails even though Object2 derives from IObject and ILockable.

我认为类似于 boost::mpl::inherit 的东西,但会生成一个具有所提供类型的所有可能排列的继承树,这可能会起作用。

我也对解决这个问题的其他方法感到好奇。理想情况下,进行编译时检查而不是运行时检查(即没有dynamic_cast)。


您可以使用递归可变参数继承编写接口检查类:

template<typename... Interfaces>
struct check_interfaces;
template<>
struct check_interfaces<> {
   template<typename T> check_interfaces(T *) {}
};
template<typename Interface, typename... Interfaces>
struct check_interfaces<Interface, Interfaces...>:
public check_interfaces<Interfaces...> {
   template<typename T> check_interfaces(T *t):
      check_interfaces<Interfaces...>(t), i(t) {}
   Interface *i;
   operator Interface *() const { return i; }
};

例如:

struct IObject { virtual int getAttribute() = 0; };
struct IMutable { virtual void setAttribute(int) = 0; };
struct ILockable { virtual void lock() = 0; };

void f(check_interfaces<IObject, IMutable> o) {
   static_cast<IObject *>(o)->getAttribute();
   static_cast<IMutable *>(o)->setAttribute(99);
}

struct MutableObject: IObject, IMutable {
   int getAttribute() { return 0; }
   void setAttribute(int) {}
};

struct LockableObject: IObject, ILockable {
   int getAttribute() { return 0; }
   void lock() {}
};

int main() {
   f(new MutableObject);
   f(new LockableObject);  // fails
}

注意check_interfaces检查的每个接口都有一个指针的足迹;这是因为它对实际参数的声明类型执行类型擦除。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中接口的多重继承 的相关文章

随机推荐

  • AngularJS:$http.get 405(不允许使用方法)

    当我收到来自 url 的请求时 如下所示 http method GET url http mooc lms dev web nd v0 3 users login success function data status headers
  • Anaconda + Spyder 中的渲染不正确(文本颜色错误)

    今天打开 Anaconda 并从中启动 Spyder 时 我遇到了一些 对我来说 无法解释的渲染问题 我不确定这是否是正确的术语 文本未按正常方式显示 请参见下面的示例图片 这是 Anaconda Navigator GUI 中的示例 ht
  • 如果西班牙语站点图像不存在,如何加载英语站点图像

    我有一个多语言网站 使用html javascript 如果西班牙语文件夹中不存在图像 则可能是ajax 它应该从英语文件夹中加载图像 路径示例 英文网站 images home jpg 西班牙网站 es images home jpg 今
  • 等到 bootstrapTable 完全加载后再执行某些操作

    我有一个基于 javascript 的 bootstrapTable 可以动态生成表和数据 我在尝试将一些 CSS 样式和类应用于某些td正在生成的这个问题 https stackoverflow com questions 3033414
  • Haskell 与 Prolog 的比较 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Prolog 比 Haskell 能更好地解决哪些问题 这两种语言之间的主要区别是什么 Edit 是否有一个可以模仿 Prolog 功能的 Ha
  • 使用 Javascript/jQuery 打开选择?

    有没有办法使用 Javascript 和 jQuery 打开选择框
  • Rails:使用 will_paginate 每页显示 10 或 20 或 50 个结果如何?

    又是我 我需要使用 will paginate 插件在我的帖子列表中显示 10 或 20 或 50 个结果每页的结果数 你能帮我吗 Thanks 看起来OP也在这里问 http railsforum com viewtopic php id
  • iptables 转发和输入

    我有一个装有 Linux 电脑的家庭网络 所有电脑都运行着 iptables 我认为将我的 LAN 放在 Linux 网关 防火墙后面更容易 所以我在我的路由器和 LAN 之间放置了一台电脑 带有 fedora 没有 gui 并配置了 ip
  • Amazon S3 预签名 URL

    如果我将我的应用程序设置为生成用于访问 S3 媒体的预签名 URL 以便我可以将文件设置为私有 除非通过登录用户访问 那么如果有人有权访问 那么我这样说是否正确到 URL 在到期时间内 他们可以看到该文件 尽管它是 私有 的 因此 如果有人
  • 重载运算符和链接

    我有一个类 其中包含存储动态二维数组的对象 矩阵 我正在尝试重载 运算符 以便将 1 个矩阵复制到另一个矩阵上 以下作品 Square Matrix a b c a b 但是 这不起作用 a b c 它给了我以下错误1 与operator
  • QUANTEDA - 无效类“dfmSparse”对象

    我收到此警告消息 我使用这些数据 https github com kbenoit quanteda tree master data data char inaugural RData https github com kbenoit q
  • OpenCV 和 CMake 的链接问题

    我正在编写一个使用OpenCV的程序 安装在本地目录中 因为我在那台机器上没有root权限 并且我已经编写了相应的CMakeLists txt文件 我的问题是编译在链接阶段以不同的方式失败 我花了三个小时尝试了网上提出的所有不同的解决方案
  • 如何获取随机 json 数据并附加到 div 元素

    说这是我的 json imageSmall images employee jpgs employees abhishek 80x80 jpg imageBig images employee jpgs employees abhishek
  • 玩 securesocial - 开发者环境和单元测试

    我们在 Play 2 应用程序中使用 securesocial 模块进行身份验证 我有两个关于这个模块的问题 首先 有没有一种简单的方法可以禁用开发环境中的授权检查 最好不注释所有内容 SecureSocial SecuredAction注
  • 使用 Python 下载共享的 Google Drive 文件夹

    我的谷歌驱动器上有一个文件夹 其中只有 jpg 图像 我想使用该文件夹的共享链接将该文件夹中的所有图像下载到我的计算机上 到目前为止 我发现唯一有效的是下面的代码 但我只能让它适用于特定的共享文件 而不是整个文件夹 from google
  • 使用 TabItem 时如何将 TabLayout 与 ViewPager 同步

    我想用TabLayout with TabItem与以下代码
  • NuGet 包文件在构建期间未复制到项目内容

    我正在使用 VS2012 professional 和 NuGet Package Manager 版本 2 2 31210 构建 MVC4 Web 应用程序 我的解决方案中有多个项目 所有项目都共享我使用 NuGet 安装的各种包 我的项
  • 基于组件的MVC框架和基于动作的MVC框架

    您好 我曾使用过 JSF 它是一个基于组件的 MVC 框架 我知道很多 Web 项目都使用 Spring 作为其技术 而 Spring 属于 基于操作的 UI 框架 类别 我想知道这里有什么区别 哪一种更先进并为用户提供更多灵活性 一些优点
  • C 线程之间的消息传递

    我试图让线程 A 与线程 B 进行通信 我应该使用线程之间的消息传递来执行此操作 但我试图找到一些解释消息传递的示例源代码 有谁有一些解释消息传递的示例源代码 C 语言 的良好链接吗 虽然没有链接 但有很多方法可以实现这一点 首先是使用套接
  • C++中接口的多重继承

    我有一个对象接口和派生对象可能想要支持的开放式接口集合 An object class IObject getAttribute 0 A mutable object class IMutable setAttribute 0 A lock