Наследование классов во время компиляции

0

Предположим, вам даны два класса A и B, интерфейс которых неизвестен заранее. Цель состоит в том, чтобы "объединить" A и B в новый класс AB во время компиляции.

Объединив, я имею в виду, что все функции-члены и все переменные-члены, а также все типы A и B присутствуют в AB с той же реализацией. Наследования классического класса не хватает; Мне нужно иметь его во время компиляции, потому что диспетчеризация времени выполнения является дорогостоящей в моем приложении. Наивное решение было бы создать экземпляр каждого класса и направить любой вызов; однако это не является общим, поскольку мы предполагаем, что интерфейс не должен быть зафиксирован заранее.

Использование понятий С++ 11 прекрасно, если это помогает. Возможна ошибка компилятора в случае конфликта в интерфейсах A и B

Задний план

Классы реализуют функции утилиты, которые основаны на некоторых внешних данных и передаются как параметр шаблона. Существует несколько типичных утилит, которые часто используются и которые я хочу учитывать (классы A, B, C), но не все они всегда применимы (если, например, применимы только A и B, то я хочу использовать служебную программу AB). Код очень низкоуровневый, и функции полезности вызываются очень часто в критическом по времени цикле.

  • 2
    Что пропустил бы класс, просто наследующий от A и B?
  • 1
    Хм, наследование происходит во время компиляции. Так что просто выведите свой класс из A и B
Показать ещё 2 комментария
Теги:
generics

3 ответа

1
Лучший ответ

Для не виртуальных функций наследование не накладывается на наследование. Поэтому просто не объявляйте ни одного из членов A или B как virtual и никакая virtual таблица не будет создана компилятором.

Минималистский пример

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

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

Nb, если A и B перекрываются, компилятор будет жаловаться на двусмысленности.

(Этот ответ основан на комментариях и дается для полноты, кредиты для комментаторов.)

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;
}
  • 0
    Какой смысл AB быть шаблоном?
  • 0
    en.wikipedia.org/wiki/...
Показать ещё 2 комментария
0

Наследование - это один из способов (возможно, предпочтительный). У вас будет небольшая проблема, если A и B содержат методы с подписями (одно и то же имя и одинаковые параметры), это трудно преодолеть без знания API перед началом работы. Вы можете попытаться проанализировать код статически, попросить программу прочитать код как текст, проанализировать API и создать новый текст вместе с API вместе, вам нужно будет решить, что делать с той же проблемой подписи (вы называете оба? в каком порядке? и т.д.). Это решение намного, намного сложнее и подвержено ошибкам.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню