Альтернативы C++ пустоте* указатели (который не является шаблонами),

Работает после удаления атрибута типа в теге скрипта. Я использую <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> перед основным тегом сценария. Это работает здесь. Также закройте тег script. Я надеюсь, что смогу помочь. Также измените

document.getElementById('#link').setAttribute('href','testPHP.php');

на

document.getElementById('link').setAttribute('href','testPHP.php');

7
задан Voltaire 3 October 2008 в 19:56
поделиться

8 ответов

Можете Вы не иметь корневого Контейнерного класса, который содержит элементы:

template <typename T>
class Container
{
public: 

   // You'll likely want to use shared_ptr<T> instead.
   virtual void push(T *element) = 0;
   virtual T *pop() = 0;
   virtual void InvokeSomeMethodOnAllItems() = 0;
};

template <typename T>
class List : public Container<T>
{
    iterator begin();
    iterator end();
public:
    virtual void push(T *element) {...}
    virtual T* pop() { ... }
    virtual void InvokeSomeMethodOnAllItems() 
    {
       for(iterator currItem = begin(); currItem != end(); ++currItem)
       {
           T* item = *currItem;
           item->SomeMethod();
       }
    }
};

Эти контейнеры могут затем быть розданы полиморфно:

class Item
{
public:
   virtual void SomeMethod() = 0;
};

class ConcreteItem
{
public:
    virtual void SomeMethod() 
    {
        // Do something
    }
};  

void AddItemToContainer(Container<Item> &container, Item *item)
{
   container.push(item);
}

...

List<Item> listInstance;
AddItemToContainer(listInstance, new ConcreteItem());
listInstance.InvokeSomeMethodOnAllItems();

Это дает Вам интерфейс Container безопасным с точки зрения типов универсальным способом.

Если Вы хотите добавить ограничения к типу элементов, которые могут содержаться, можно сделать что-то вроде этого:

class Item
{
public:
  virtual void SomeMethod() = 0;
  typedef int CanBeContainedInList;
};

template <typename T>
class List : public Container<T>
{
   typedef typename T::CanBeContainedInList ListGuard;
   // ... as before
};
3
ответ дан 6 December 2019 в 05:49
поделиться

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

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

14
ответ дан 6 December 2019 в 05:49
поделиться

Используя полиморфизм, Вас в основном оставляют с базовым классом для контейнера и производными классами для типов данных. Базовый класс / производные классы может иметь столько виртуальных функций, сколько Вам нужно в обоих направлениях.

Конечно, это означало бы, что необходимо будет перенести примитивные типы данных в производные классы также. При пересмотре использования шаблонов в целом, это - то, где я использовал бы шаблоны. Сделайте один производный класс из основы, которая является шаблоном, и используйте это для примитивных типов данных (и другие, где Вам больше не нужна функциональность, чем обеспечивается шаблоном).

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

1
ответ дан 6 December 2019 в 05:49
поделиться

Во-первых, всех, шаблоны и полиморфизм являются ортогональными понятиями, и они действительно играют хорошо вместе. Затем, почему Вы хотите определенную структуру данных? Что относительно STL или структур данных повышения (конкретно указатель containter) не работает на Вас.

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

3
ответ дан 6 December 2019 в 05:49
поделиться

Полиморфизм и шаблоны действительно играют очень хорошо вместе при использовании их правильно.

Так или иначе я понимаю, что Вы хотите сохранить только один тип объектов в каждом контейнерном экземпляре. Если так, используйте шаблоны. Это будет препятствовать тому, чтобы Вы хранили неправильный тип объекта по ошибке.

Что касается контейнерных интерфейсов: В зависимости от Вашего дизайна возможно, Вы сможете сделать их шаблонными также, и затем у них будут методы как void push(T* new_element). Думайте о том, что Вы будете знать об объекте, когда Вы захотите добавить его к контейнеру (неизвестного типа). Куда объект прибудет из во-первых? Функция, которая возвращается void*? Вы знаете, что это будет Сопоставимо? По крайней мере, если все сохраненные классы объектов определяются в Вашем коде, можно заставить их всех наследоваться от общего предка, скажем, Storable, и используйте Storable* вместо void*.

Теперь, если Вы видите, что объекты будут всегда добавляться к контейнеру методом как void push(Storable* new_element), затем действительно не будет никакой добавленной стоимости в создании контейнера шаблон. Но затем Вы будете знать, что это должно сохранить Storables.

5
ответ дан 6 December 2019 в 05:49
поделиться

Вы могли бы также хотеть проверить Библиотеку проверки понятия повышения (BCCL), которая разработана для обеспечения ограничений на шаблонные параметры шаблонных классов, контейнеры в этом случае.

И только повторить, что сказали другие, у меня никогда не было проблемы при смешивании полиморфизма и шаблонов, и я сделал некоторый довольно сложный материал с ними.

1
ответ дан 6 December 2019 в 05:49
поделиться

Вам не придется бросить подобные Java интерфейсы и использовать шаблоны также. Предложение Josh's универсального основного шаблона Container, конечно, позволило бы Вам, действительно полиморфно раздают Контейнеры и их детей, но дополнительно Вы могли, конечно, реализовать интерфейсы как абстрактные классы, чтобы быть содержавшими объектами. Нет никакой причины, Вы не могли создать абстрактный класс IComparable, поскольку Вы предложили, такой, что у Вас могла быть полиморфная функция следующим образом:

class Whatever
{
   void MyPolymorphicMethod(Container<IComparable*> &listOfComparables);
}

Этот метод может теперь взять любого ребенка Контейнера, который содержит любой класс, реализовывая IComparable, таким образом, это было бы чрезвычайно гибко.

0
ответ дан 6 December 2019 в 05:49
поделиться

Простая вещь состоит в том, чтобы определить названный абстрактный базовый класс Container, и разделите его на подклассы для каждого вида объекта, который можно хотеть сохранить. Затем можно использовать любой стандартный класс набора (std::vector, std::list, и т.д.) для хранения указателей на Container. Следует иметь в виду, что, так как Вы сохранили бы указатели, необходимо будет обработать их выделение/освобождение.

Однако то, что Вам нужен единственный набор, чтобы хранить объекты таких дико различных типов, является признаком, что что-то может быть неправильным с дизайном Вашего приложения. Может быть лучше пересмотреть бизнес-логику перед реализацией этого суперуниверсального контейнера.

5
ответ дан 6 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: