Как сделать указатель на вектор с

Добавил пользователь Евгений Кузнецов
Обновлено: 05.10.2024

На С я использую указатели на функции, чтобы имитировать полиморфизм:

> Интересует ещё такой вопрос, приходилось ли кому-нибудь использовать
> указатели на функции в реальной работе? А указатели на методы классов?
>
Да, много раз. указатель для функции может быть удобен при создании
таблицы, которая должна выполнить определенную операцию в зависимости
от конкретного параметра. Например, указатель на функцию может быть
очень удобно использовать, если пишется интерпретатор. Но это уж как
кто работает.
--
We are all going to hell and I'm driving the bus

Posted via ActualForum NNTP Server 1.4

> А указатели на методы классов?

Для этого есть виртуальные методы.

Posted via ActualForum NNTP Server 1.4

> Для этого есть виртуальные методы.
Не всегда удобно. См. VCL модель эвентов.
--
We are all going to hell and I'm driving the bus

Posted via ActualForum NNTP Server 1.4

Posted via ActualForum NNTP Server 1.4

> Интересует ещё такой вопрос, приходилось ли кому-нибудь использовать
> указатели на функции в реальной работе? А указатели на методы классов?
Шутишь ? Как правило ни одно API без них не обходится. Пол WinAPI на коллбэках,
это те же указатели на функции. Ну и вообще очень часто используется.
Например, в стандартной библиотеке С указатель на функцию сравнения
элементов используется в реализации quick sort - функция qsort.

Posted via ActualForum NNTP Server 1.4

> Для этого есть виртуальные методы.

В С-то ? Толя на С пишет сейчас. :-)
На голом !

Posted via ActualForum NNTP Server 1.4

> Для этого есть виртуальные методы.

> Однако и указателей на методы классов в С который без классов наверное
> тоже нету? :)
Вот объясни, кто тебе мешает считать методом любую процедуру/функцию,
где первым параметром идет this - указатель на структуру?
--
We are all going to hell and I'm driving the bus

Posted via ActualForum NNTP Server 1.4

> В С-то ? Толя на С пишет сейчас. :-)
> На голом !

Ну, ну, это std::vector это голый Си?

Posted via ActualForum NNTP Server 1.4

Мне нужно используя pVec узнать размер вектора и вытащить укзатель на [n] элемент. Как можно такое провернуть?

Задача впринципе - отображать массивы в свойствах объекта в редакторе

anz
> Как можно такое провернуть?
static_cast<>, reinterpret_cast<>.

anz
> Я знаю что pVec - это точно указатель на vector

Указатель на вектор или на первый элемент данных вектора?

В первом случае

Он же вроде как ничего не знает о типе в том участке кода, кроме размера.

чувствуется запашок орхетиктуры.

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

anz
> Задача впринципе - отображать массивы в свойствах объекта в редакторе
А как именно редактор дергает свойства объекта? Объекты же наверняка полиморфные и все такое.

anz
Попробуй для начала сделать структуру/класс с энумератором.

и через тип type передавать тип массива. Или с указателем pVeс передавать Transfer_type type;

s3dworld
> static_cast<>, reinterpret_cast<>.
в том то и дело, не известно к чему кастить

0iStalker
> Указатель на вектор или на первый элемент данных вектора?
указатель на вектор

Более подробно:
есть система рефлексии. Есть объект, поля которого нужно вытащить в редактор. На каждое поле у меня есть его тип и смещение относительно начала объекта, владеющего полем.
Когда строю UI в редакторе бегу по полям, смотрю что у него за тип, в зависимости от этого создаю UI поле. Значение достаю по смещению.
Попадается поле-вектор. Нужно показать все элементы вектора. Где сам вектор я знаю, какой тип элемента я знаю (в своей системе рефлексии).
Размер и указатели на элементы массива мне нужно узнать, чтобы вывести их по аналогии с простыми полями.

anz
> Мне нужно используя pVec узнать размер вектора и вытащить укзатель на [n]
> элемент. Как можно такое провернуть?

anz
> в том то и дело, не известно к чему кастить
anz
> Я знаю что pVec - это точно указатель на vector

какое то противоречие.

Kartonagnick
я так понимаю у него то место где pVec заполняется и где кастуется это два разных "приложения".

foxes
> кастуется это два разных "приложения"
Почти, суть та же

В таких случаях подцепляют описание (.hpp от myType и инклуд вектора), и каст будет работать
Если знаешь размер myType и не важно, что там внутри, создай фальшивый объект myType нужного размера
А вообще смысл этих действий странный, может тебе Variant использовать и не париться

geletka
> Если знаешь размер myType и не важно, что там внутри
у него myType это множество типов динамически выбран только один, а не один статично выбранный.

Я у себя просто сделал IVectorAPI с методами GetItem/SetSize/GetSize, а затем при регистрации vector записываю указатель на экземпляр имплементирующий это API в описание типа vector .

Объясните, пожалуйста, можно ли вектора выражать динамически или какая у меня тут ошибка) А может подход вовсе неверный?

С ошибкой всё просто. Во-первых, необъявленная переменная student_spisok . Во-вторых, полагая, что student_spisok — это скорее всего вектор string ФИО студентов, ты в return возвращаешь значение типа string . А в сигнатуре метода у тебя указан тип возвращаемого значения std::vector . Нестыковочка. Видимо в сигнатуре метода должно быть std::string .

Из вышесказанного следует, что студент должен содержать данные только о себе, значит поле std::vector students из объявления убираем. Если нам нужно много студентов, значит делаем контейнер, который может хранить несколько студентов. Контейнером может быть массив, вектор, список и т.п. Конкретный вид контейнера надо выбирать исходя из потребностей.

Хорошо, с этим разобрались. Идём дальше: надо привести в порядок набор методов класса. Методы

удаляются однозначно, поскольку относятся к контейнеру, в котором хранятся студенты.

Метод void set_scores(int[]) вместе с int scores[5] оставим на совести первоисточника. (Я бы использовал для хранения оценок вектор.)

Странно, что для набора оценок есть метод-сеттер, но нет метода-геттера. Ну и ладно, пока он вроде не нужен. Но в уме галочку поставим.

Самый весёлый метод: void set_averge_ball(float) . У студента Иванова текущие отметки (scores) двойки и тройки, а мы тут вызвали set_averge_ball и установили Иванову средний балл 4.88. Да?

Одно из правил ООП: данные в объекте должны всегда быть в непротиворечивом состоянии. Метод void set_averge_ball(float) нарушает это правило. Средний балл однозначно зависит от оценок, которые содержатся в переменной scores . Здесь метод-сеттер противопоказан. А вот метод-геттер — вполне законен.

Вычисление среднего балла может быть выполнено двумя способами: либо при добавлении очередной оценки пересчитывается средний балл и запоминается в переменной float averge_ball , либо средний балл вычисляется каждый раз, когда вызывается метод get_averge_ball . Хотя более оптимальным будет третий способ: вычислять среднее арифметическое только при первом вызове get_averge_ball после любого изменения оценок, а потом возвращать кэшированное значение из переменной averge_ball . Кодить хлопотнее, но производительность будет выше. (В данном случае, конечно, на производительность наплевать, но такие маленькие хитрости всегда надо держать в уме.)

Как итог, сделанный на скорую руку в одном файле эскиз программы. (Объявление класса должно быть в отдельном файле, реализации всех методов — тоже должны быть в отдельном файле, как правильно сделано у топикстартера.)

Для интересующихся в качестве бонуса несколько упражнений ;-)

В малый джентльменский набор методов класса я добавил операторы для вывода лога на консоль. Объясните вывод программы.

Можно ли оптимизировать работу с памятью при добавлении студента в группу? Как?

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

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

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

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Наконец-то, начинаю цикл статей о том, что меня больше всего привлекает - программирование.

Цепочка статей будет посвящена чистому языку С. Прежде чем начать программировать на языках с объектным подходом, необходимо научится хорошо это делать на процедурных языках. Язык С - это необходимая классика, которую нужно понимать, поскольку идеи данного языка лежат в основе многих других, в том числе объектно-ориентированных языках. Не говоря даже о синтаксисе, основной каркас которого, по сути, стал неким стандартом в мире программирования.

Поэтому, начнем с простого, но нетривиального для данного языка. А именно - структура данных вектор на основе динамических массивов. Вообще понятие структуры данных свойственно больше объектным языкам, где очень удобно воспользоваться классом для этой задачи. Но вот вдруг нам хочется написать игру под Linux с использованием библиотеки для подобия графики в терминалах ncurses и хранить структуры пуль в векторе? Но в таком случае хочется удобной и сладкой жизни с удобным интерфейсом для работы с памятью и массивами. Поэтому сделаем некое подобие вектора (vector в C++, ArrayList в Java и т.д) на основе структуры с несколькими полями, которая будет заменять нам объект вектора, и обычных функций, которые будут работать со "структурой-объектом" и выполнять роль методов класса. Сразу стоит отметить, что программировать будем как минимум на 99 стандартах языка, где уже есть for и т.д.

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

Читайте также: