编译时类继承

时间:2014-06-10 11:28:12

标签: c++ generics

假设您有两个类AB,其接口事先未知。目标是一般地“结合”' {em} AB编译时进入名为AB的新类。

通过组合,我的意思是所有成员函数和所有成员变量以及AB的所有类型都存在于AB中,具有相同的实现。经典的类继承是不够的;我需要在编译时使用它,因为运行时调度在我的应用程序中是昂贵的。天真的解决方案是创建每个类的实例并转发任何调用;然而,这不是通用的,因为我们假设接口不能提前修复。

使用概念C ++ 11如果有帮助就没问题。如果AB的接口发生冲突,则编译器错误是可以接受的。

背景

这些类实现了基于某些外部数据的实用程序函数,并作为模板参数传递。有几个典型的实用程序经常使用,我想要分解(类ABC),但并非所有实例都始终适用(例如,仅{{} 1}}和A适用,然后我想使用实用程序B)。代码非常低级,实用程序函数通常在时间关键的循环中被称为非常

3 个答案:

答案 0 :(得分:1)

对于非虚函数,继承不会产生运行时开销。因此,只需AB的任何成员声明为virtual,编译器不会创建任何vtable。

简约的例子是

struct A { void f() { /* ... */ } };
struct B { void g() { /* ... */ } };

struct AB : public A, public B { };  // Provides both f and g.

N.b。,如果AB重叠,编译器会抱怨含糊不清。

(这个答案是基于评论的,并且是为了完整性而给出的;信用是给评论员的。)

答案 1 :(得分:0)

我确信这已经在其他地方得到了解决 - 您正在寻找的是静态继承。实现这一目标的两种模式是基于策略的设计和奇怪的重复模板。小心超载问题。

#include <iostream>

using namespace std;

class A
{
public:
  int a;
  A() : a(0) {}
  int foo_A() { return a; }
};

class B
{
public:
  int b;
  B() : b(1) {}
  int foo_B() { return b; }
};

template<class stinh1, class stinh2>
class AB : public stinh1, public stinh2
{

};


int main()
{
  AB<A,B> ab;
  cout << ab.foo_A() << endl << ab.foo_B() << endl;
  ab.a = 2;
  ab.b = 3;
  cout << ab.foo_A() << endl << ab.foo_B() << endl;
}

答案 2 :(得分:0)

继承是一种方法(可能是最好的方式)。如果A和B包含具有签名(相同名称和相同参数)的方法,那么您将遇到一个小问题,如果不事先知道API,这很难克服。 您可以尝试静态分析代码,让程序将代码读作文本,解析API并创建两个API组合的新文本,您需要决定如何处理相同的签名问题(您同时调用它们吗?按什么顺序?等等')。这种解决方案更加困难,更容易出错。