Полиморфизм — неуверенный в классе с использованием шаблонов — функция с поддержкой функции возвращает тип шаблона

Недавно я решил поработать над проектом, в котором мне нужно иметь один объект, который может быть любого типа данных (uint8, unint16, uint32 или unint64) (я могу добавить, что это только цифры и будет только +, -, *, /, <<>> Я заглянул в Boost :: варианту, однако после того, как я его опробовал, он был обескуражен, так как не смог правильно извлечь данные. ааааа — подача заявок ?? Поэтому я посмотрел на другие методы, чтобы подражать этому.

Ниже этой точки эксперименты, и, кажется, неправильно, очень неправильно:

(Я хотел бы сказать, что я не слишком углублен в полиморфизм / наследование, поэтому извините заранее)
Я попытался создать базовый объект, а затем установить базовый объект на производный класс — класс производного шаблона, который является типом данных по моему выбору (uint8, uint16, uint32 или uint64). После этого я могу просто получить данные, которые Я ранее установил с помощью метода get ():

DynamicVariable *a = new TypedDynamicVariable<unsigned int>(12345);
std::cout << a->get() << std::endl;
delete a;

или же:

DynamicVariable *a = new TypedDynamicVariable<unsigned char>(255);
std::cout << a->get() << std::endl;
delete a;

пример представления:

unsigned int  a = 100;
unsigned char b = 20;
std::cout << a + b << std::endl;

приводит к: ошибка C2039: «получить»: не является членом «DynamicVariable»

Я получаю ошибки, которых a-> get () не существует в классе BASE. Я искал в Интернете, чтобы найти этот код (dynamic_cast):

DynamicVariable *a = new TypedDynamicVariable<int>(12345);
TypedDynamicVariable<int>* p = dynamic_cast<TypedDynamicVariable<int>*>(a);
std::cout << p->get() << std::endl;

Как видите, это: TypedDynamicVariable *< int>* и dynamic_cast *> (a) (указав, что это INT) для меня побеждает всю цель того, что я хотел бы делать.

Ниже приведен класс, который я взломал вместе из-за многих неуверенных часов чтения онлайн. Кажется, у меня есть общее описание моего «решения», однако я действительно знаю, что отсутствует важное содержание, которое нуждается в улучшении или нуждается в улучшении, или на самом деле полиморфизм — это не то, что мне нужно, / я не могу его использовать.

class DynamicVariable
{
public:
//constructor & virtual destructor
DynamicVariable() {}
virtual ~DynamicVariable() {}

};

//unique data
template<typename T>
class TypedDynamicVariable : public DynamicVariable
{
private:
T _data;

public:
//constuctor
TypedDynamicVariable    (const T& data) : _data(data) { }

//prototypes
void    set             (const T& data) { _data = data; }
T       get             (void)          { return _data; }
};

Если кто-нибудь может помочь мне понять, что не так с приведенным выше классом, и направить меня к рабочему решению, или указать мне правильное направление с помощью Boost :: Вариант, если они действительно то, что я искал в конце концов.

Благодарю.

2

Решение

это

DynamicVariable *a = <some initialisation>
std::cout << a->get() << std::endl;
delete a;

не работает, потому что компилятор должен знать, как вызвать a->get() не зная, какой производный тип a на самом деле указывает на. По этой причине только те члены, которые являются частью aобъявленные (статические) типы рассматриваются и get не один из них.
Это та же проблема, с которой сталкиваются Boost.Variant и Boost.Any.

В конце концов, все сводится к одной простой вещи: если вы не знаете, какой тип значения в настоящее время хранится в boost::variant<>/boost::any/DynamicVariableтогда вы не сможете получить это значение.
Для Boost.Variant вы получаете значение с boost::get<type>(variant), Для Boost.Any вы получаете значение с boost::any_cast<type>(any), За DynamicVariable вам, вероятно, придется сделать что-то подобное.

0

Другие решения

ты можешь использовать boost::variant если определенные типы хорошо известны во время компиляции (вы должны предоставить список для его создания). и только тот типы могут быть сохранены в варианте. тогда вы можете использовать посетителей, чтобы сделать что-то с сохраненными данными (см. также which() член-функция).

В качестве альтернативы вы можете использовать boost::any без каких-либо ограничений на содержащиеся типы данных.

Написание собственного варианта (почти) невозможно реализовать в терминах традиционного ООП: Потому что вам нужно написать get() член с другим типом возврата (неизвестно во время компиляции). (что невозможно в C ++).

и ваша текущая оболочка (в основном) бесполезна с точки зрения полиморфизма — вы можете иметь контейнер указателей на ваш базовый класс, но не можете понять, что хранится внутри … так что вы не можете get() что-нибудь из этого хранилища с данными, хранящимися в нем. Вы должны предоставить несколько методов для этого. и они должны использовать RTTI как-то … так что с точки зрения производительности это будет далеко от совершенства … лучше использовать boost::variant

0

Чтобы иметь возможность звонить get() из класса матери DynamicVariableВам нужно, чтобы этот метод был определен как виртуальный (чистый в вашем случае). Итак, вопрос в том, что это за тип get() метод в DynamicVariable вернется? Не пытайтесь найти фокус с шаблонами, виртуальные методы не могут быть шаблонами.

Я не большой поклонник boost :: variable или boost :: any (даже если они полезны!), Иногда это слишком простой способ решения проблем проектирования.

В качестве альтернативы я бы действительно подумал о приложении, которое вы имеете в виду (я думаю, что ваш пример упрощен). Задайте себе следующий вопрос: имеют ли разные типы общее значение?

  • Если да, то вам следует рассмотреть возможность наследования и для возвращаемого типа: метод get() возвращает указатель на родительский класс, скажем GeneralReturnType и дочерние реализации возвращают указатели на классы, которые являются производными от GeneralReturnType,
  • Если нет, то вам просто не следует звонить get() от DynamicVariable класс: другой тип возвращаемого значения не имеет общего значения, поэтому get() Метод имеет различное значение в зависимости от класса TypedDynamicVariable считается. Чтобы позвонить get() метод, поэтому вы должны знать, какой у вас производный класс (возможно, полиморфизм — это не то, что вам нужно, действительно …).
0
По вопросам рекламы [email protected]