Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

Передача объекта параметром и последующее изменение - C++

26.01.2010, 16:08. Просмотров 782. Ответов 3
Метки нет (Все метки)

Неразбериха с классами.
Я создаю экземпляр класса,и далее указатель на него его передаю параметром самому себе.Так можно вообще делать? Заранее извиняюсь за бред,т.к. классы я учу "в процессе".
Выглядит всё это примерно так:
C++
1
2
3
4
5
expr_Node_t *operand1 = syntax_Primary(vars,arrays,labels);
//   ...
operand2 = syntax_Primary(vars,arrays,labels);
operand1->NewBinOp (operand1,operand2,OP_DIVIDE);
//   ...
В функции же происходит следующее:
C++
1
2
3
4
5
6
7
8
9
10
  expr_Node_t *Expression::NewBinOp (expr_Node_t *object,
                                     expr_Node_t *operand2, OpKind oper)
  {
     expr_Node_t *operand1 = new expr_Node_t (*object); // резервируем объект перед изменением
     kind                = EK_BINOP;
     data.binop.kind     = oper;
     data.binop.operand1 = operand1;
     data.binop.operand2 = operand2;
     return this;
  }
Зарезервировать объект,я думаю,необходимо перед изменением,так как все поля data внутри класса - unions (вроде бы анонимные,судя по сообщениям gcc),выглядят так:
union
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        union
        {
           ...
           struct {                 // Unary operation
              OpKind kind;
              expr_Node_t *operand;
           } unop;
           struct {                 // Binary operation
              OpKind kind;
              expr_Node_t *operand1;
              expr_Node_t *operand2;
           } binop;
         ...
        } data;

Имеет ли это смысл вообще?
Будет ли это работать?
Нужно ли писать конструктор-копировщик в этом случае?
Целью этого всего является построение древовидной структуры из экземпляров класса,как вы догадались.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.01.2010, 16:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Передача объекта параметром и последующее изменение (C++):

Передача функции параметром - C++
первый раз с этим дело имею, вот хотел с std::function разобраться, делаю что то вроде: int func(int) { return 0; } ... int func()...

ООП в C++: Вызов родительского конструктора с параметром при создании объекта дочернего класса - C++
Здравствуйте! Столкнулся с такой проблемой: если есть родительский класс с конструктором, то при создании дочернего объекта от этого...

Передача объекта методу другого объекта другого класса - C++
Всем привет. Есть у меня класс test1, который имеет конструкторы только с параметрами. Другой класс test2 имеет конструктор, который...

Передача объекта в метод - C++
void delete_value(string value, list<films> coll) coll передаётся как копия. После удаления из копии данные из списка, который был...

Передача объекта в функцию - C++
подскажите что тут не так у меня?! /* * 5. Поле first — целое положительное число, часы; * поле second — целое положительное...

Передача объекта в функцию - C++
Нужно передать в функцию void Openz(Array &a) { int**buff = a.getarr(); for (int i(0); i < 10; i++) { for (int j(0);...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,525
Записей в блоге: 26
26.01.2010, 21:55 #2
C++
1
operand1->NewBinOp (operand1,operand2,OP_DIVIDE)
Насколько я понимаю, сия строка должна создавать новый экземпляр класса. А ты пытаешь существующий экземпляр затащить сам в себя. Если я правильно понимаю то, что ты хочешь, то это должно выглядеть как

C++
1
operand1 = new expr_Node_t (operand1,operand2,OP_DIVIDE); // <-- это конструктор для создания двухоперандного узла
а то, что у тебя сделано в качестве NewBinOp, должно быть конструктором.

Поскольку в твоём случае все expr'ы создаются динамически и вообще не должны копироваться друг в друга (имею в виду не должны копироваться экземпляры класса, указатели конечно же можно), то я бы вообще сделал copy-конструтор, в котором влепил бы вызов Fatal, т.к. таких действий быть не должно

Добавлено через 21 минуту
"это конструктор для создания двухоперандного узла" читать как "инициализации"

В твоём примере ты инициализируешь поля существующего экземпляра. А надо инциализировать поля вновь созданного экземпляра. Т.е. вместо "kind = EK_BINOP" должно быть "operand1->kind = EK_BINOP" и т.д. А вместо "return this" должно быть "return operand1". При таком подходе идеологически это перестаёт быть методом класса, а является обычной функцией

В Си++ есть возможность в одном операторе создать новый объект в динамической памяти и вызвать процедуру для инициализации полей (оператор new). В Си нет возможности, а потому там обычно создаётся функция, внутри которой делается выделение памяти и инициализация полей
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
26.01.2010, 22:34  [ТС] #3
Да,надо тут обмозговать.Просто когда всё перевёл на классы,оказалось,что нужно или менять структуру построения дерева,или идти на какие-то хитрости.Я недаром привел этот код:
C++
1
2
3
4
expr_Node_t *operand1 = syntax_Primary(vars,arrays,labels);
...
operand2 = syntax_Primary(vars,arrays,labels);
operand1->NewBinOp (operand1,operand2,OP_DIVIDE);
То есть operand1 уже инициализирован на время вызова NewBinOp,и в случае просто числа,а не двухаргументной операции его нужно возвратить из функции.Если же создавать ещё один операнд,который вместит два операнда и операцию,то тогда встаёт проблема,что и когда возвращать из функции.
А моя цель была просто выделить память под объект,инициализировать её,а потом уже менять исходный объект,делая его уже вместилищем для двух операндов,и тогда оба операнда "не потеряются"
***
Вообще у меня такой общий вопрос начинающего созрел для С++: вот есть в Си какие-то данные,содержащиеся в неком сегменте памяти,а в С++ есть экземпляры классов.Можно ли работать в С++ с экземпляром класса также как просто с неким отрезком памяти,также её копировать,то есть с точки зрения указателей ничего не меняется?
0
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,525
Записей в блоге: 26
26.01.2010, 22:59 #4
Для начала опишу более подробно, что я имел в виду в предыдущем посте:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class expr_Node_t
{
  // Конструктор для формирования двухаргументной операции
  expr_Node_t (const expr_Node_t *operand1, const expr_Node_t *operand2, OpKind oper);
  ...
};
...
 
expr_Node_t::expr_Node_t (const expr_Node_t *operand1, const expr_Node_t *operand2, OpKind oper)
{
     kind                = EK_BINOP;
     data.binop.kind     = oper;
     data.binop.operand1 = operand1;
     data.binop.operand2 = operand2;
}
 
...
expr_Node_t *operand1 = syntax_Primary(vars,arrays,labels);
//   ...
operand2 = syntax_Primary(vars,arrays,labels);
 
// Здесь мы создаём узел и сразу же к нему подвешиваем два уже существующих узла
// Указатель operand1 больше не нужен, ибо это только указатель. Технически этот момент
// исполняется аналогично коду
//
// expr_Node_t *tmp = malloc (...);
// tmp->constructor_expr_Node_t (operand1,operand2,OP_DIVIDE);
// operand1 = tmp
//
// Т.е. ничего у тебя не потеряется
operand1 = new expr_Node_t (operand1,operand2,OP_DIVIDE);
...
> То есть operand1 уже инициализирован на время вызова NewBinOp

operand1 - это УКАЗАТЕЛЬ. Это не объект. Он у тебя указывает на какой-то экземпляр класса, выделенный в памяти. Далее этот указатель ты передал в конструктор вновь созданного объекта. Внутри конструктора этот указатель у тебя запомнился. Теперь в operand1 мы записали указатель на вновь созданный объект. А operand1->data.binop.operand теперь смотрит туда, куда до вызова new смотрел operand1

> А моя цель была просто выделить память под объект,инициализировать её,а потом уже менять исходный объект

Не совсем понятно, зачем, но тогда это должно выглядеть так:

C++
1
2
3
tmp = new expr_Node_t;
tmp->NewBinOp (operand1,operand2,OP_DIVIDE);
operand1 = tmp;
При этом из NewBinOp выкидывается new, метод становится void и переименовывается во что-то типа InitBinOp, поскольку он уже только инициализирует, но новый экземпляр не создаёт. Всё это можно было бы написать в виде одной строки, как я указал выше

> Можно ли работать в С++ с экземпляром класса также как просто с неким отрезком памяти,также её копировать,то есть с точки зрения указателей ничего не меняется?

Можно. Но Си++ на то и разрабатывали, чтобы в программе вот таких вот ковыряний было как можно меньше. Либо приведи более конкретный пример, что ты имеешь в виду
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2010, 22:59
Привет! Вот еще темы с ответами:

Передача объекта в метод - C++
Объясните пожалуйста,как правильно написать. Есть метод AddMessage() который добавляет сообщение в тему,и есть метод GetMessage() который...

Передача объекта в вызывающую функцию - C++
Всем привет! Что-то меня переклинило, помогите. Задача в том, что в функции, вызванной из main(), нужно построить довольно тяжелый объект,...

Передача объекта класса в функцию С++ - C++
Всем привет! Возник вопрос по классам. Допустим мне нужно изменить объект класса через функцию вызываемую в main. Я пробовал через...

Передача объекта структуры по ссылке - C++
Здравствуйте. Нужно использовать передачу структуры по ссылке(или по указателю). Объясните пожалуйста как это делать и , если можно, как...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.01.2010, 22:59
Ответ Создать тему
Опции темы

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