简体   繁体   中英

Compile-time class inhertiance

Suppose you are given two classes A and B whose interface is not known in advance. The goal is to generically 'combine' A and B into a new class called AB at compile time .

By combining I mean that all member functions and all member variables as well as all types of both A and B are present in AB with the same implementation. Classical class inheritance does not suffice; I need to have it at compile time because run-time-dispatching is to costly in my application. The naive solution would be to create an instance of each class and forward any call; this is not generic, however, because we assume the interface not to be fixed in advance.

Using concepts C++11 is fine if that helps. A compiler error in case of a conflict in the interfaces of A and B is acceptable.

Background

The classes implement utility functions that are based on some external data and are passed on as a template parameter. There are several typical utilities that are often used and that I want to factor out (classes A , B , C ), but not all are always applicable (if for example only A and B are applicable, then I want to use the utility AB ). The code is very low-level and the utility functions get called very often within a time-critical loop.

For non-virtual functions no run-time overhead is incurred by inheritance. So simply do not declare any of the members of A or B as virtual and no vtable will be created by the compiler.

A minimalistic example is

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

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

Nb, if A and B overlap, the compiler will complain about ambiguities.

(This answer is based on the comments and is given for completeness sake; credits are to the commentators.)

I'm sure this has been addressed elsewhere already - what you're looking for is static inheritance. Two patterns implementing this are policy based design and curiously recurring templates. Beware of overloading issues.

#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;
}

Inheritance is one way to go (probably the preferable one). You will have a small issue if A and B contain methods with the signature (same name and same parameters), this is hard to overcome without knowledge of the API before hand. You could try to analyze the code statically, have a program read the code as text, parse the API and create a new text with both APIs combined, you will need to decide what to do with the same signature problem (do you call both? at what order? etc'). This solution is much, much harder and more prone to errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM