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

Передача параметра, выделенного в куче, в функцию

09.05.2013, 21:59. Просмотров 593. Ответов 13
Метки нет (Все метки)

Доброго времени суток. Возник такой вопрос.
Пусть имеется некоторый класс, под объект которого выделяется память:
C++
1
SomeClass pClass = new SomeClass();
И есть функция, которая принимает этот объект в качестве аргумента, копирует его внутри себя и не редактирует его. Так вот, как более корректно передавать этот объект в функцию?
C++
1
2
3
4
5
6
SomeFunc (const SomeClass &_someClass)
{
SomeClass someClass = new SomeClass (_someClass);
}
...
SomeFunc (*pClass);
или
C++
1
2
3
4
5
6
SomeFunc (SomeClass *_someClass)
{
SomeClass someClass = new SomeClass (*_someClass);
}
...
SomeFunc (pClass);
или
C++
1
2
3
4
5
6
SomeFunc (SomeClass _someClass)
{
// просто используем _someClass
}
...
SomeFunc (*pClass);
В первом случае выглядит как-то коряво, передавать ссылку на объект в куче через разыменование. Во втором теряется гарантия того, что объект не будет изменён. В последнем объект скопируется в стек, что не критично, но хотелось бы этого не делать.
Благодарю за ответы.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.05.2013, 21:59
Ответы с готовыми решениями:

Передача параметра в функцию
Проблема заключается в следующем. Есть функция, вот её прототип. void attachInterrupt(uint8_t...

Передача параметра в функцию
Столкнулся с муторной проблемой передачи параметра в функцию. Суть задания такая, что нужно...

Передача параметра в функцию класса
Здравствуйте. Столкнулся с проблемой. Почему переменная "x" не становится равна 25? #include...

Передача параметра string в функцию
Приветствую. List<string> get_match_code(string code) { string _temp1 =...

13
499 / 349 / 93
Регистрация: 22.03.2011
Сообщений: 1,111
09.05.2013, 22:25 2
C++
1
2
3
4
5
6
7
8
9
class A {}; //некоторый класс
 
void foo(A obj) {} // передача в функцию по значению, создаеться копия обьекта черещ конструктор копирования (С++ стиль)
void foo(A& obj) {} // передача в функцию по ссылке (С++ стиль)
void foo(const A& obj) {} //передача в функцию по ссылке при этом обьект константен
 
void foo(A* obj) {} // передача в функцию по указателю (Си стиль)
void foo(const A* obj) {} // передача в функцию по указателю при этом обьект константен
void foo(const A* const obj) {} // передача в функцию по указателю при этом обьект и указатель константны
Ответ на лично Ваш вопрос, так как Вам надо так и делайте.
1
0 / 0 / 0
Регистрация: 09.05.2013
Сообщений: 6
09.05.2013, 22:50  [ТС] 3
Да дело то в том, что мне по большому счёту без разницы, работают все три варианта. Я хотел разобраться, какой метод в таком случае более приемлем.
Наверное лучше использовать передачу по значению, раз всё равно объект копировать, тем более, что размер его вряд ли превысит 30кб.
0
499 / 349 / 93
Регистрация: 22.03.2011
Сообщений: 1,111
09.05.2013, 22:58 4
Цитата Сообщение от -OggY- Посмотреть сообщение
Наверное лучше использовать передачу по значению, раз всё равно объект копировать,
Да. И нет)

Есть еще такое понятие как std::move. Если кратко то оно меняет местами "внутренние" указатели.
C++
1
2
3
4
void foo(const A& obj) //нету копирования
{
A copy = std::move(obj); //тоже нету копирования, но при этом обьект obj уже не валиден
}
0
5477 / 4872 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
10.05.2013, 00:29 5
Цитата Сообщение от -OggY- Посмотреть сообщение
В первом случае выглядит как-то коряво, передавать ссылку на объект в куче через разыменование
Нет там разыменования.
Цитата Сообщение от -OggY- Посмотреть сообщение
Во втором теряется гарантия того, что объект не будет изменён
Передавайте указатель на const.
Цитата Сообщение от -OggY- Посмотреть сообщение
В последнем объект скопируется в стек, что не критично, но хотелось бы этого не делать.
Не делайте.
1
0 / 0 / 0
Регистрация: 09.05.2013
Сообщений: 6
10.05.2013, 00:40  [ТС] 6
Цитата Сообщение от alsav22 Посмотреть сообщение
Нет там разыменования.
Как это? А что же тогда такое *pClass ?
Цитата Сообщение от alsav22 Посмотреть сообщение
Передавайте указатель на const.
Я так понимаю, это
C++
1
SomeClass *const _someClass
но не
C++
1
const SomeClass *_someClass
?

Еще вопрос про первый случай (который я посчитал корявым), возникают ли в нём какие-то ненужные копирования или выделения на стеке?
0
499 / 349 / 93
Регистрация: 22.03.2011
Сообщений: 1,111
10.05.2013, 00:45 7
Наоборот все что слева от * относиться к константности обьекта, справа указателя.

C++
1
2
const Class *obj консантный обьект
const Class * const obj консантный обьект и указатель
не забывайте что указатель это тоже число.
1
5477 / 4872 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
10.05.2013, 01:25 8
Запутали. Что вы, собственно, разыменовываете если:
C++
1
SomeClass pClass = new SomeClass();
Может так?
C++
1
SomeClass *pClass = new SomeClass();
Добавлено через 21 минуту
Цитата Сообщение от -OggY- Посмотреть сообщение
Еще вопрос про первый случай (который я посчитал корявым), возникают ли в нём какие-то ненужные копирования или выделения на стеке?
По-моему, при передаче по ссылке, в любом случае (и в этом "корявом"), в функцию передаётся указатель (адрес). Поэтому, если есть указатель, нет смысла в передаче по ссылке, через разыменование указателя.
1
0 / 0 / 0
Регистрация: 09.05.2013
Сообщений: 6
10.05.2013, 10:50  [ТС] 9
Цитата Сообщение от alsav22 Посмотреть сообщение
Может так?
Да, конечно же ) Проглядел.
0
Tulosba
10.05.2013, 11:46
  #10

Не по теме:

-OggY-, для разбора того, чем является идентификатор в С/С++ удобно пользоваться правилом "спирали":
http://c-faq.com/decl/spiral.anderson.html

1
0 / 0 / 0
Регистрация: 09.05.2013
Сообщений: 6
10.05.2013, 19:03  [ТС] 11
Коллеги со Stack Overflow убедили меня, что третий вариант самый приемлемый в моей ситуации, поскольку мне в любом случае нужна копия объекта, а 30кб (предполагаемый размер объекта) - не так страшно для стека на короткий период времени.
Всем спасибо за ответы.
0
5477 / 4872 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
10.05.2013, 20:06 12
Если нужна локальная копия и размер объекта небольшой, то да. Тогда небольшое уточнение по коду: если нужна локальная копия, то, в первом и втором варианте, необязательно выделять память в куче.
0
:)
Эксперт С++
4763 / 3257 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
10.05.2013, 20:09 13
Цитата Сообщение от -OggY- Посмотреть сообщение
копирует его внутри себя и не редактирует его
А где-то после копирования есть вообще редактирование? Может быть копия не нужна вовсе?
0
0 / 0 / 0
Регистрация: 09.05.2013
Сообщений: 6
10.05.2013, 21:45  [ТС] 14
Цитата Сообщение от Tulosba Посмотреть сообщение
А где-то после копирования есть вообще редактирование?
Да конечно, копия сильно меняется впоследствии, иначе вопросов бы не возникало )
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.05.2013, 21:45

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Передача строчного параметра в функцию
Имеется на VB следующий код: Dim buf_data As String Set ob = CreateObject('Mylib.Myobj')...

Передача параметра в функцию сортировки
function Example(c, d) { return (a, b) => { if (a - b) { return c } else { return d...

Передача массива в функцию в качестве параметра
Всем привет! Файл с реализацией: int Init_can::Send(int* msgdata) { //Send canmsg_t tx;...

Передача потока как параметра в функцию
Дорогие форумчане! Повторяю пример из книжки, пока остановился из-за ошибки. //Программа...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.