Как `композитный элемент C++ без функций add()/insert() etc`
Привет Эксперты
У меня есть шаблон класса C++ CompositeElement, который содержит поле / свойство CompositeElement** (указатель на указатель). Я знаю, что это не точное намерение composite состоять из структуры данных, содержащей многомерные полиморфные деривации и/или шаблонные специализации самой себя (имя не является проблемой в моем вопросе).
Как я могу построить примерный экземпляр с 4 уровнями рекурсивного вложения наборов классов внутри себя (под свойством/полем CompositeElement**).
Мне нужно решить эту проблему без использования std::vector / std::set / std::map, просто указателей C++98 C99, конструкторов и назначений. Он должен быть в общей библиотеке ("*.so") специализированный обходной путь при создании экземпляра с фиктивной функцией файла "*.cpp". Построение из файла client *.cpp с использованием этой библиотеки.
некоторые экспериментальные незрелые я разработал
спасибо
Что я уже пробовал:
разработанный пример .
#ifndef COMPOSITION_LIBRARY_HEADER #define COMPOSITION_LIBRARY_HEADER namespace compositionlib{ template <class T> class __attribute__ ((visibility("default"))) CompositeElement{ public: // Default Constructor explicit __attribute__ ((visibility("default"))) CompositeElement( ); // Specialized Template Argument Constructor explicit __attribute__ ((visibility("default"))) CompositeElement( T const& payload ); // Copy Constructor explicit __attribute__ ((visibility("default"))) CompositeElement( CompositeElement const& other ); // Copy Constructor with contents explicit __attribute__ ((visibility("default"))) CompositeElement( CompositeElement const& other, T const& payload ); const std::auto_ptr< T >& getData() const; const size_t & getSize() const; private: const size_t m_size; const std::auto_ptr<T> m_data; public: bool m_isCopiedConstructed; // CompositeElement __attribute__ ((visibility("default"))) m_CompositeElementData; incomlete type CompositeElement __attribute__ ((visibility("default"))) *m_ptrOfCompositeElementData; CompositeElement __attribute__ ((visibility("default"))) **m_setOfCompositeElementData; }; } #endif //COMPOSITION_LIBRARY_HEADER
Stefan_Lang
Я добавил тег C++ к вашему форматированию. Тем не менее, это все еще трудно понять, если вы не предлагаете никакой информации о том, что означает __attribute__ and ((visibility("default"))).
Кроме того, ключевое слово "явный" - это C++11 или более поздняя версия-я думал, вы хотите C++98?
Rick York
Я понятия не имею, что означает "4 уровня рекурсивного вложения наборов классов внутри себя". Я знаю, что такое вложенные или встроенные классы, но где в это вписывается рекурсивность? Также непонятно, почему вы должны иметь " 4 уровня."
Вы уверены, что вам нужны операторы __attribute__ для всех конструкторов и членов? Я делаю это только для самого класса, так как вы почти всегда хотите экспортировать весь класс, а не только определенные методы.
Наконец, вы должны пересмотреть использование auto_ptr, потому что он имеет недостатки и устарел. Теперь следует использовать unique_ptr или shared_ptr. Как правило, unique_ptr будет достаточно, но если вам нужно передать право собственности на указатель, то следует использовать shared_ptr.
Stefan_Lang
Если вам нужен код, совместимый с C++98 (или любым более поздним стандартом), вы не можете использовать расширения GCC, такие как __attribute__, и в глобальном пространстве имен нет типа size_t: для C++98 он доступен только в пространстве имен std.
Более того, AFAIK для C++98 все пространство имен std все еще было скрыто внутри подпространства tr1, и ничто из этого технически не было частью стандарта. Большинство компиляторов, совместимых с C++98 (если не все), предоставляли реализации std::tr1, но если они это делали, то либо предоставляли реализации контейнеров STL вместе с auto_ptr, либо вообще не предоставляли STL. Поэтому, если вы думаете, что можете использовать auto_ptr, нет никаких причин не использовать vector или другой контейнер STL.
Если вы ограничены в использовании очень специфического компилятора, например GCC X. Y, то скажите так, а не C++98! Это существенная разница!
Audiory Researcho
I try to avoid a simplified initialization of 1D/2D/3D where it can be defined with arrays in a simple manner, 4D represent a complicated multidimensional setup to prevent easy escape from understanding the context of my interest in this question - building sparse multidimensional features vector space for machine learning. (in final usage it might go up to 1000 dimensions features vector space ). I am sure the __attribute__ is not necessary in some of the places, it emphasis that these data fields/properties will be accessed from outside the *.dll/*.so module (that is the client module - might be built with different compile/pre-processor/link switches)
извините, если это вызовет другие не благоговейные мысли.
Audiory Researcho
вы совершенно правы. Я не знаю, как написать это как допустимый код с C++98, поэтому на первом шаге я притворяюсь, что это C++98, используя только синтаксис C++98 и интеллектуальные указатели, оставляя экспорт символов завершенным после решения корневого вопроса. можете ли вы помочь мне экспортировать общую библиотеку с помощью C++98 ? Что касается использования auto_ptr, то это экономит мне усилия и интеграцию инструментов сборки, связанных с boost::shared_ptr для C++98. архитектура и дизайн знаний сводятся к голому вопросу о том, как создать экземпляр класса XxxClass{ some_smarty_ptr<> data; XxxClass ** m_dptrXxxClassArray; }; с 4-кратной многомерной структурой данных.
Audiory Researcho
Спасибо, я начинающий вопрошатель вопросов /: ...
Stefan_Lang
Я не уверен, что смогу вам помочь. До сих пор вы не предложили описание вашей проблемы таким образом, чтобы мы могли ее понять.
Можете ли вы рассказать нам, что у вас есть и чего вы хотите достичь? Пожалуйста, помните, что мы не можем видеть то, что находится на вашем столе, и мы не можем читать ваши мысли.
Audiory Researcho
Извините, я думаю, что мне нужен другой формат дискуссионной доски, чтобы загрузить проект, чтобы вы могли просмотреть то, что у меня есть. мне нужно инициализировать XxxClass ** х = новый XxxClass *[3];
x[0,1,2] = новый XxxClass(значение[0,1,2])
теперь возьмите 3 элемента этой конструкции в одну конструкцию
Класс XxxClass{
XxxClass ** m_setOfXxxClassObjs;
} у, Z;
y.m_setOfXxxClassObjs = новый XxxClass *[3];
г.m_setOfXxxClassObjs[0,1,2] = х[0,1,2];
теперь сложите y в z.m_setOfXxxClassObjs[...]
и так далее... рекурсивно-конструктивно
Stefan_Lang
О, я не имел в виду загрузку всего проекта, это, вероятно, было бы чересчур.
Что касается структуры данных, то сколько элементов вы собираетесь хранить и сколько уровней рекурсии вы собираетесь использовать? Вы где-то упомянули, что данные на самом деле скудны. Но если это так, то вам понадобится гораздо больше памяти только для того, чтобы построить ту структуру указателей, которую вы предлагаете здесь, чем для реальных данных! Не говоря уже о том, что хранение или извлечение элемента будет медленным.
Единственный разумный способ решить эту проблему-это использовать карту: вместо того чтобы использовать вектор значений индекса для идентификации элемента, вы бы объединили эти значения в одно число: хэш. И это хэш-значение затем может быть использовано для хранения и извлечения вашего элемента в карте. std::map может сделать все это за вас.
Audiory Researcho
карта / хэш-это не вариант. только простой простой указатель исчерпывающего векторного пространства span style. Я уже почти решил ее сам. спасибо за ваши усилия, я подумаю о том, чтобы поделиться проектом ( я действительно не понимаю, как измеряется репутация и оценка в S. O.).
Stefan_Lang
Что ж, это твой выбор. Просто говорю, что STL старше любого стандарта C++, и мой совет был бы точно таким же еще в 1998 году. Изобретать велосипед редко бывает хорошей идеей. Особенно если ваша версия выглядит как квадрат.