Чистые виртуальные методы с разными типами данных - PullRequest
0 голосов
/ 15 апреля 2011

Я создаю базовый класс для своих контейнерных классов, чтобы я мог поддерживать согласованный интерфейс.В настоящее время это выглядит примерно так:

template <typename Datatype>
class BaseClass
{
    public:
    virtual Datatype Foo() = 0;
    virtual Datatype Bar() = 0;
};

template <typename Datatype>
class DerivedClass: public BaseClass<Datatype>
{
    public:

    virtual Datatype Foo()
    {
    }

    virtual Datatype Bar()
    {
    }
};

Однако, с некоторыми из моих производных классов, Foo() и Bar() могут иметь разные типы возвращаемых значений друг от друга.Не имея параметра шаблона для каждого отдельного возвращаемого типа в базовом классе, как я могу дать производным классам некоторое пространство для изменения такого рода вещей?

РЕДАКТИРОВАТЬ:

Типы производных классовиспользование потенциально совершенно разные и инвариантные.На самом деле, производные классы не обязательно имеют какие-либо точки соприкосновения, кроме имен методов.

Ответы [ 6 ]

6 голосов
/ 15 апреля 2011

Укажите черту, которая будет специализироваться в тех случаях, когда вам нужен другой результат.

template <typename Datatype>
struct BaseTraits
{
    typedef Datatype FooResult;
    typedef Datatype BarResult;
};

template <typename Datatype, typename Traits = BaseTraits<Datatype> >
class BaseClass
{
    public:
    virtual Traits::FooResult Foo() = 0;
    virtual Traits::BarResult Bar() = 0;
};
3 голосов
/ 15 апреля 2011

Если вы заранее знаете количество потенциальных типов, вы можете расширить то, что получили, добавив дополнительные типы в шаблон базового класса ...

template <typename FOO_TYPE,typename BAR_TYPE>
class BaseClass
{    
public:    
    virtual FOO_TYPE Foo() = 0;    
    virtual BAR_TYPE Bar() = 0;
};

template <typename FOO_TYPE,typename BAR_TYPE>
class DerivedClass: public BaseClass<FOO_TYPE,BAR_TYPE>
{    
public:    
    virtual FOO_TYPE Foo()    {    }    
    virtual BAR_TYPE Bar()    {    }
};

Это может быстро выйти из-под контроля, если у вас есть несколько типов.

1 голос
/ 15 апреля 2011
#include <iostream>
#include <typeinfo>

using namespace std;

template <typename T, typename R = T>
class base
{
  public:
    virtual R foo() 
    {
      cout << "foo(): data type = " << typeid(T).name() << endl; return R();
    }

    virtual R bar()
    {
      cout << "bar(): return type = " << typeid(R).name() << endl; return R();
    }
};

int main()
{
  base<int> b;
  base<int, long> b1;

  b.foo(); b.bar();
  b1.foo(); b1.bar();

  cout << typeid(b).name() << endl;
  cout << typeid(b1).name() << endl;

  return 0;
}

Приведенная выше программа вернула следующее:

С g++:

$ ./rettypetemplate
foo(): data type = i
bar(): return type = i
foo(): data type = i
bar(): return type = l
4baseIiiE
4baseIilE

С Visual Studio 2005 cl.exe:

C:\Program Files\Microsoft Visual Studio 8\VC>rettypetemplate.exe
foo(): data type = int
bar(): return type = int
foo(): data type = int
bar(): return type = long
class base<int,int>
class base<int,long>

Хотя в этом примере показано, как это сделать, ответ, данный AProgrammer , показывает хороший способ обработки с использованием черт.Приведенный выше пример будет хорошо работать для основных типов данных, но не для пользовательских типов.Для обработки пользовательских типов, черты - путь.Чтобы узнать больше о чертах, обратитесь к книге "Шаблон C ++" от Jossutis или к " Современный дизайн C ++ ".

1 голос
/ 15 апреля 2011

НЕ возможно return разных типов данных.Единственным способом было бы сделать методы template, и это ограничено, потому что virtual методы не могут быть шаблонами.

1 голос
/ 15 апреля 2011

черты могут помочь. Книга C ++ - Полное руководство содержит пример, иллюстрирующий это, в главе, озаглавленной Черты характера и политики . В нем есть пример, который использует аккумулятор для возврата различных типов.

РЕДАКТИРОВАТЬ : я вижу AProgrammer уже привел пример

1 голос
/ 15 апреля 2011

Если возвращаемые типы являются ко-вариантами, они могут быть изменены, или вы можете написать какую-то функцию преобразования и иметь что-то вроде real_bar или что-то в этом роде.

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