Доступ к членам шаблонного класса, созданного с различными аргументами шаблона - PullRequest
1 голос
/ 30 июля 2010

Мой основной класс проекта - шаблонный класс, объявленный с:

template<int dim, typename typ>

где dim - число измерений (2 или 3), а typ - тип данных с плавающей запятой (с плавающей запятой или двойной). На основании этих параметров экземпляры этого класса имеют свои члены определенного типа, а векторы (математические) имеют dim количество компонентов.

Таким образом, экземпляры могут различаться по типам элементов, а их функции различаются по типам параметров, но все они имеют одинаковое расположение функций ... что можно сделать для времени выполнения, то есть для общего доступа к функциям экземпляров этого класса, созданных с использованием разных аргументы шаблона ???

1 Ответ

3 голосов
/ 30 июля 2010

Это именно то, для чего предназначено наследование. Вы создаете общий, не шаблонный, чисто виртуальный базовый класс, который определяет интерфейс, используемый всеми вашими шаблонами, например ::10000

class Base {

  public:

    virtual ~Base() {};

    virtual void foo() = 0;

    virtual int bar(int param) = 0; 

    // Etc, for whatever other methods you want
};

Затем вы извлекаете из него свой шаблон:

template<int dim, typename typ>
class Dervied : public Base
{
  public:

    virtual ~Derived();

    virtual void foo();

    virtual int bar(int param); 

    // Etc, for whatever other methods you want   

  private:

    std::vector<typ> data;
};

И, конечно же, реализовать методы для шаблона Derived. Затем вы можете получить доступ к любому экземпляру Derived через указатель или ссылку на Base. Например:

void callFoo(const Base& b)
{
   b.foo();
}

int main() 
{
  Derived<3,float> d_f3;
  Derived<2,double> d_d2;

  callFoo(d_f3);
  callFoo(d_d2);

  return 0;
}

Из вашего описания звучит так, что могут существовать некоторые методы, которые являются общими для всех экземпляров Derived, но некоторые из них зависят от параметров шаблона, например,

void addNumber(typ number);

В этом случае вы не можете перетащить эту функцию в Base, так как не имеет смысла вызывать этот метод для Derived<n,float>. Если есть некоторые функции, которые зависят от типа, и некоторые, которые зависят от числа, то вы можете создать базовые классы, инкапсулирующие эти идеи, например:

class Base 
  { /* All methods independent of template parameters */ };

template <int dim> DimBase : virtual public Base
  { /* All methods dependent only on the dimension parameter */ };

template <typename typ> TypBase : virtual public Base
  { /* All methods dependent only on the type parameter */ };

template<int dim, typename typ>
  Derived : public DimBase<dim>, public TypBase<typ>
  { /* All methods */ };

Это позволит вам вызывать любой независимый метод, используя указатель или ссылку Base, вызывать любой метод, зависящий от измерения, используя указатель или ссылку DimBase<n>, и любой метод, зависящий от типа, используя указатель TypBase<T> или ссылка.

Обратите внимание, что в приведенном выше описании рекомендуется, чтобы Base, TypBase и DimBase были абстрактными классами (содержащими хотя бы один не реализованный виртуальный метод), и существенный , что 1032 * и DimBase наследуются от Base с использованием virtual public вместо просто public, в противном случае вы получите " страшный алмаз "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...