Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.90/29: Рейтинг темы: голосов - 29, средняя оценка - 4.90
0 / 0 / 1
Регистрация: 01.03.2017
Сообщений: 32
1

Передача типа переменной через аргумент функции

16.10.2017, 19:01. Показов 5966. Ответов 28
Метки нет (Все метки)

Стоит задача: реализовать свой вариант динамических массивов без использования STL(т.е. без new, как я понимаю). При этом должно работать не только для стандартных типов данных. Я решил, что память буду выделять malloc-ом, но столкнулся с проблемой. Если бы нужно было реализовывать только для стандартных типов, то я бы просто перегрузил функцию для разных типов, но тогда это не будет работать для пользовательских типов.
Думал сделать как-нибудь через шаблоны, что-то типо:

C++
1
2
3
4
template <typename T>
void memoryAlloc(T ptr, int length) {
ptr=(T*)malloc(sizeof(*ptr)*length);
}
В общем вся суть: как можно реализовать поддержку любого пользовательского типа?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.10.2017, 19:01
Ответы с готовыми решениями:

Неверная передача массива через возвращаемое значение функции типа int**
Не могу понять причину неработоспособности кода. Прошу помочь и объяснить! Пользуюсь исключительно...

Передача переменной типа double из c# в переменную типа float в SQL
Здравствуйте, имеется проблема с передачей данных из кода c# в бд SQL Имеется переменная типа...

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

Передача функции в аргумент
Есть три функции: void MainMenu(); void MainMenu_MilkMenu(); bool ErrorMenu(void (*pf)()); ...

28
27 / 27 / 16
Регистрация: 22.08.2017
Сообщений: 126
16.10.2017, 19:11 2
В общем случае new при создании объекта запускает конструктор объекта. А malloc не запускает конструктор объекта. А delete и delete [] запускает деструктор объекта. А free не запускает деструктор объекта. Есть конечно placement_new, но как-то странно использовать malloc и с ним placement_new. Кстати, деструктор тоже надо запускать все равно при освобождении памяти.
0
0 / 0 / 1
Регистрация: 01.03.2017
Сообщений: 32
16.10.2017, 19:15  [ТС] 3
к сожалению тонкости работы new я не изучал, мне нужно просто реализовать динамическое выделение памяти без использования new для любого типа данных, т.е. как я понимаю с помощью malloc/realloc

Добавлено через 1 минуту
UPD: забыл указать - реализовать нужно класс реализующую «динамический массив элементов произвольного типа»
0
27 / 27 / 16
Регистрация: 22.08.2017
Сообщений: 126
16.10.2017, 19:16 4
мне нужно просто реализовать динамическое выделение памяти без использования new для любого типа данных
В общем случае "любой тип данных" это в том числе и пользовательский класс с нетривиальным конструктором и деструктором. Если у Вас учебная задача, то имеет смысл уточнить у преподавателя, что именно имелось ввиду. Напишите ему в вотсапе вопрос прямо сейчас.

UPD: забыл указать - реализовать нужно класс реализующую «динамический массив элементов произвольного типа»
Похоже, что это и есть пользовательский класс с нетривиальным конструктором и деструктором. Или даже массив элементов пользовательского класса с нетривиальным конструктором и деструктором.
0
0 / 0 / 1
Регистрация: 01.03.2017
Сообщений: 32
16.10.2017, 19:22  [ТС] 5
Точная формулировка: Создать программу, реализующую класс «динамический массив элементов произвольного типа» без использования стандартной библиотеки C++. Предусмотреть возможность добавления, удаления элементов в любую часть массива.
Самая глупая реализация - создать класс в котором будут указатели всех стандартных типов и соответствующие методы выделения/освобождения памяти. И как аргумент типа string передавать необходимый тип. Но даже столь недалекий человек как я понимает, что данных вариант не подходит.
Еще думал как-то сделать через void*. Может есть мысли какие у вас
0
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 19:28 6
почти правильно. не хватает одного и одно лишнее и не правильное:
C++
1
2
3
4
5
6
7
8
9
template <typename T>
void* memoryAlloc() {
  return malloc(sizeof(T));
}
 
template <typename T>
void* memoryAlloc(size_t count) {
  return malloc(sizeof(T)*count);
}
В целом можно свести и к одной функции и для одного объекта отдавать еденицу.
Функции специально возвращают void*, а не T*.
для встроенных и POD типов можно было бы и Т* созвращать, но для польовательских объекты надо
еще и конструировать. Т.е. явно для них конструктор вызывать. А это вроде как доступно только для
placement new. возможно такой new и не попадает под ваши ограничения. В зависимости от того, будете
вы его применять или нет будет зависеть и деструкция.

увидел в последнем сообщении упоминание стандартной библиотеки. так вот placement new не из стандартной библиотеки,
это оператор языка с++. поэтому использовать можно. да и выделение под не POD типы без него вы не сделаете скорее всего.

и кстати, операторы new и delete тоже часть языка, а не библиотеки, в отличае от функций типа malloc/free. Поэтому возможно вы
перестарались и надо использовать new/delete
0
0 / 0 / 1
Регистрация: 01.03.2017
Сообщений: 32
16.10.2017, 20:08  [ТС] 7
Добавлено через 35 минут
Я не понимаю как правильно использовать, разъясните пожалуйста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class DinMemory {
public:
    DinMemory() {}
    DinMemory( int s ) {
        size = s;
    }
private:
    int  size;
    template <typename T>
    void* memoryAlloc(size_t count) {
        return malloc(sizeof(T)*count);
    }
    
    ~DinMemory() {  }
};
 
 
void main() {
    DinMemory *obj = new DinMemory();
    double *ptr = obj->memoryAlloc(3); // вот здесь проблемка и возникает, "отсутствует экземпляр шаблон функции"
    
 
}
0
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 20:13 8
C++
1
double *ptr = obj->memoryAlloc<double>(3);
ну и явный каст надо делать. я написал вам причины выше. вчитайтесь еще раз.


но это скорее все не то. возможно от вас хотят, чтобы сам класс DinMemory был шаблонным. Впрочем, вам виднее.
0
7158 / 6133 / 2801
Регистрация: 14.04.2014
Сообщений: 26,455
16.10.2017, 20:15 9
Если "реализующую класс", то какой ещё malloc? Правильно говорят - задание уточни.
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
16.10.2017, 20:59 10
Цитата Сообщение от 25th_July Посмотреть сообщение
Создать программу, реализующую класс «динамический массив элементов произвольного типа» без использования стандартной библиотеки C++
Если нельзя использовать стандартную библиотеку, то при чем тут new? new - это не стандартная библиотека.
0
0 / 0 / 1
Регистрация: 01.03.2017
Сообщений: 32
16.10.2017, 21:18  [ТС] 11
согласно вики: https://ru.wikipedia.org/wiki/... B0_C%2B%2B new относится к ней
0
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 21:26 12
это потому что в с++ путаница с этим.
есть оператор new. его поведение переопределить нельзя. это часть языка.

а есть функция, у которой название: operator new. вот она входит в стандартную библиотеку и ее можно переопределять. стандартные функции живут в <new>. в вики это и написано.
http://www.cplusplus.com/refer... tor%20new/

то же относится к delete
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
16.10.2017, 21:29 13
Цитата Сообщение от 25th_July Посмотреть сообщение
согласно вики: https://ru.wikipedia.org/wiki/... B0_C%2B%2B new относится к ней
Там речь об операторах new и delete, а выражение new - это часть языка.
И вряд ли твой преподаватель имел в виду это, когда давал задание. Но если так хочется побороться с ветряными мельницами, то можно переопределить операторы new и delete на свои.
C++
1
2
3
4
5
6
7
8
void* operator new(size_t sz) 
{
    return ::malloc(sz);
}
void operator delete(void* ptr) noexcept
{
    ::free(ptr);
}
Тогда ты будешь совершенно чист в этом аспекте. Правда, повторюсь, преподаватель наверняка имел в в виду не это, а использование алгоритмов и классов-контейнеров из стандартной библиотеки. Чтобы студент смог продемонстрировать умение работать с памятью самостоятельно.

Добавлено через 49 секунд
Цитата Сообщение от DU3 Посмотреть сообщение
это потому что в с++ путаница с этим.
Нет в С++ никакой путаницы
Путаница есть только в русских переводах англоязычных терминов.
0
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 21:30 14
да я уже упоминал об этом. вот он перепишет их или продолжыт юзать маллоки как щас. разве malloc/free не часть стандартной библиотеки? может тогда надо платформспецифик апи вызывать да еще и на асме. в общем еще раз:
автор, вы перестарались и в своем рвении не юзать стандартное как раз таки его и заюзали.

как же нет путаницы. хотите сказать, что new, sizeof, typeid и прочее - это не операторы, а выражения? если так, то ладно. как бы там ни было, путаница в именовании или в переводах таки имеется.
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
16.10.2017, 21:42 15
Цитата Сообщение от DU3 Посмотреть сообщение
вот он перепишет их или продолжыт юзать маллоки как щас. разве malloc/free не часть стандартной библиотеки?
Часть стандартной библиотеки Си. Если он будет подключать stdlib.h, вместо cstdlib и т.д., то ничего не нарушит
Но это все борьба с ветряными мельницами. В задании про стандартную библиотеку сказано исключительно для того, чтобы студент не возомнил себя самым умным и не подключил сразу класс vector с чувством выполненного долга

Добавлено через 1 минуту
Цитата Сообщение от DU3 Посмотреть сообщение
хотите сказать, что new ... - это не операторы, а выражения? если так, то ладно.
Именно.
И это не я хочу сказать, а говорит стандарт языка.
Можно вполне свободно почитать об этом тут: http://en.cppreference.com/w/cpp/language/new

Добавлено через 3 минуты
typeid и sizeof - это операторы.
new - это выражение. которое приводит к вызову оператора new для распределения памяти, а затем обеспечивает вызов конструктора, если это требуется для заданного типа. По ссылке про это написано.
0
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 21:43 16
ну если там дальше комнуть, то:
http://en.cppreference.com/w/c... #Operators
An expression is a sequence of operators and their operands
далее там в среди прочих new упоминается в качестве оператора
1
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
16.10.2017, 22:55 17
Цитата Сообщение от DU3 Посмотреть сообщение
ну если там дальше комнуть, то:
Ну и что?
Как это отменяет тот факт, что new-expression и operator new - это четко разделенные сущности в языке?
Вот есть стандарт: http://www.open-std.org/jtc1/s... /n4618.pdf
Вот есть параграф о new (5.3.4):
The new-expression attempts to create an object of the type-id (8.1) or new-type-id to which it is applied.
The type of that object is the allocated type.
Вот в нем пункт об операторе:
A new-expression may obtain storage for the object by calling an allocation function (3.7.4.1). If the
new-expression terminates by throwing an exception, it may release storage by calling a deallocation func-
tion (3.7.4.2). If the allocated type is a non-array type, the allocation function’s name is operator new
and the deallocation function’s name is operator delete
. If the allocated type is an array type, the allocation
function’s name is operator new[] and the deallocation function’s name is operator delete[].
И в списке операторов в параграфе 2.12 имеется в виду именно operator new, перегружаемая операторная функция аллокации. И везде в стандарте она упоминается именно в этом контексте. В то время как выражение new четко описано в 5.3.4 (часть процитирована выше) и эти понятия никогда не путаются. Поэтому я продолжаю настаивать, что вот это:
Цитата Сообщение от DU3 Посмотреть сообщение
в с++ путаница с этим
неправда. В C++ нет путаницы, т.к. путаницы нет в стандарте, который этот язык описывает. Путаница может быть в головах у авторов книг, переводчиков, вики-писателей и т.п. Но в С++ путаницы нет.
1
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.10.2017, 23:37 18
Как это отменяет тот факт, что new-expression и operator new - это четко разделенные сущности в языке?
никак. речь не об этом была. то, что вы пункты из стандарта привели никак не отменяет что в с++ есть
1. оператор new
2. функция с именем operator new.

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

возвращаясь к изначальному вопросу:
что new, sizeof, typeid и прочее - это не операторы, а выражения?
ваш ответ:
typeid и sizeof - это операторы.
new - это выражение. которое приводит к вызову оператора new для распределения памяти, а затем обеспечивает вызов конструктора, если это требуется для заданного типа. По ссылке про это написано.
согласно ссылке на ресурс, который вы привели - все три штуки - это операторы.
последовательность операторов с операндами есть выражение согласно определению с того же ресурса.
new от этого не перестает быть оператором.

выделенное в вашем ответе по мне запросто может запутать непосвященного. выражение с оператором new не вызывает
оператор new, оно вызывает функцию с именем operator new ну и так далее. Вот еще вариант путаницы:
Вопрос в тесте на английском: можно ли переопределить оператор нью? Два варианта ответа. Да. Нет.
Оба правильные, если дать соответствующие пояснения, но без них можно и не угадать, что там имел в виду автор.

Спорить о наличии\отсутствии путаницы я не буду. Восприятие этого дело - вещь субъективная. для вас нет путаницы, для меня она есть
1
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
17.10.2017, 00:02 19
Цитата Сообщение от DU3 Посмотреть сообщение
1. оператор new
2. функция с именем operator new.
Это одно и то же. Оператором в стандарте называется operator new (там самая функция) и больше ничего.
Путают в русских переводах выражение new (new-expression) и оператор new. Путаница заключается в том, что выражение new
C++
1
new T; // выражение new
называют оператором и функцию аллокации называют оператором. За выражением new стоит следующая механика:
C++
1
new T(); // вызов ::operator new(sizeof(T)) и вызов для полученной памяти конструктора T()
. Но я говорю о том, что в языке C++ этой путаницы нет, что подтверждаю ссылками на стандарт.

Цитата Сообщение от DU3 Посмотреть сообщение
согласно ссылке на ресурс, который вы привели - все три штуки - это операторы.
По ссылке, которую я привел, оператором называют функцию аллокации (и только), как и положено:
The new-expression allocates storage by calling the appropriate allocation function. If type is a non-array type, the name of the function is operator new.
За остальную часть ресурса я не могу отвечать, т.к. ссылок на нее не давал. Этот ресурс - вики-страница, авторы которой непостоянны и обладают непроверенной квалификацией, в том числе могут находиться в плену тех же заблуждений, что и автор темы. Если я дал ссылку на какую-то страницу этого ресурса, это не означает автоматически, что остальное содержимое так же согласуется с мыслью, которую я хотел подтвердить. Поэтому я выше даже не стал пытаться анализировать приведенные тобой ссылки, а сразу обратился к первоисточнику.

Цитата Сообщение от DU3 Посмотреть сообщение
Вопрос в тесте на английском: можно ли переопределить оператор нью? Два варианта ответа. Да. Нет.
Оба правильные, если дать соответствующие пояснения, но без них можно и не угадать, что там имел в виду автор.
Если в таком тесте под оператором имеется в виду выражение new (new-expression), то тест просто некорректен.

Цитата Сообщение от DU3 Посмотреть сообщение
выделенное в вашем ответе по мне запросто может запутать непосвященного. выражение с оператором new не вызывает
оператор new, оно вызывает функцию с именем operator new ну и так далее.
Нет не может. Даже если он просто забьет в онлайн переводчик, то он увидит, что new-expression не переводится как оператор new. Совершенно очевидно, что ты все еще находишься в плену навязанного русской литературой о С++ терминологического изъяна, поэтому и делаешь подобные выводы.
1
282 / 230 / 114
Регистрация: 07.09.2016
Сообщений: 584
17.10.2017, 07:17 20
Буду признателен, если ты освободишь меня из плена.

Я посмотрел на http://www.open-std.org/jtc1/s... /n4618.pdf
И вот какие у меня вопросы:

Что означает раздел 2.12 Operators and punctuators? Присутствующий в табличке new это оператор, пунктуатор или что-то другое? Если что-то другое, то что и почему его поместили в этот раздел?

Как понимать предложение из первого абзаца в разделе 5?
An expression is a sequence of operators and operands that specifies a computation.
Попадает ли new-expression под это определение, или это какая-то отдельная вещь в себе? Если вещь в себе, то где это можно вычитать? Если под определение попадает, то не мог бы ты прояснить свое толкование следующей строки:
new int(0);
- Что тут оператор(ы)?
- Что тут операнд(ы)?
-Если тут new - не оператор, то какая роль в этой строке у ключевого слова new и в каком пункте стандарта это определено? Как отличать оператор new, упомянутый в 2.12 от того, что в представленной строке?
- Если здесь new - это оператор, то отличается ли эта штука от функции аллокации памяти с именем "operator new" или это одно и тоже? Если это одно и тоже, то в каких пунктах стандарта это явно или неявно определено? Если не одно и тоже, то можно ли переопределить этот оператор (не функцию выделения памяти, а оператор)?

Как понимать фразу из пункта 5.3.4?
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types.
Почему акцент сделан на слове "new", а не как в большинстве других мест, которые мне попались на глаза:
"operator new", или "operator new function" или "allocation function operator new" или new-expression?

Добавлено через 33 минуты
И еще любопытно было бы узнать, как следует понимать популярного автора следующих строк:
It occasionally seems as if people went out of their way to make C++ terminology difficult to understand. Case in
point: the difference between the new operator and operator new. When you write code like this,
string *ps = new string("Memory Management");
the new you are using is the new operator. This operator is built into the language and, like sizeof, you can't
change its meaning: it always does the same thing. What it does is twofold. First, it allocates enough memory to
hold an object of the type requested. In the example above, it allocates enough memory to hold a string object.
Second, it calls a constructor to initialize an object in the memory that was allocated. The new operator always
does those two things; you can't change its behavior in any way.
What you can change is how the memory for an object is allocated. The new operator calls a function to perform
the requisite memory allocation, and you can rewrite or overload that function to change its behavior. The name
of the function the new operator calls to allocate memory is operator new.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.10.2017, 07:17

Передача числа через аргумент командной строки
Здравствуйте. Мне необходимо передать число в программу, а затем работать с этим числом. ...

Передача массива как аргумент функции
Здравствуйте! Не подскажете - как передать функции массив как аргумент без использования Variant?...

Передача динамического массива как аргумент функции
Вот кусок кода. Если разкомментировать вывод элементов массива на экран в main, то происходит...

Какого типа должен быть 3-ий аргумент функции make_heap?
make_heap(Iterator first,Iterator last,Compare comp); Так вот: &quot;Как написать 3-ий параметр?&quot; Я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru