Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:09
Оценка:
Проблема такая. Переписываю старую прогу с старого билдера 5 на MS VS2005
Там был такой класс, как Array. Судя с использования — массив указателей + плюс разные примочки(добавить/убрать элемент).
Так как VC++ я не нашёл подобного класса, решил использовать вектор с stl.
В общем имеем такой код
class Foo
{

}

class Bar
{
private:
  vector<Foo> foo;
}

Bar *bar = new Bar();

Вопрос. Нужно ли в конструкторе/деструкторе класса Bar какие то дополнительные манипуляции с классом Foo? На данный момент даже скомпилировать не могу свой код — там ещё на недельку-другую переделывать.
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re: Инициализация полей класса
От: dip_2000 Россия  
Дата: 21.08.07 09:15
Оценка:
class Foo
{

}

class Bar
{
private:
  vector<Foo> foo;
}

Bar *bar = new Bar();

OV>Вопрос. Нужно ли в конструкторе/деструкторе класса Bar какие то дополнительные манипуляции с классом Foo? На данный момент даже скомпилировать не могу свой код — там ещё на недельку-другую переделывать.
Зависит от того, что вы хотите
По тому, что у вас написано — будет создан пустой вектор с количеством элементов равным 0.
При уничтожении объекта Bar пямять занимаемая вектором будет особождена автоматически(разумеется если у вас там храняться указатели — память на которую они ссылаются будет потеряна).
Re: Инициализация полей класса
От: Bell Россия  
Дата: 21.08.07 09:15
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Проблема такая. Переписываю старую прогу с старого билдера 5 на MS VS2005

OV>Там был такой класс, как Array. Судя с использования — массив указателей + плюс разные примочки(добавить/убрать элемент).
OV>Так как VC++ я не нашёл подобного класса, решил использовать вектор с stl.
OV>В общем имеем такой код
OV>
OV>class Foo
OV>{

OV>}

OV>class Bar
OV>{
OV>private:
OV>  vector<Foo> foo;
OV>}

OV>Bar *bar = new Bar();
OV>

OV>Вопрос. Нужно ли в конструкторе/деструкторе класса Bar какие то дополнительные манипуляции с классом Foo? На данный момент даже скомпилировать не могу свой код — там ещё на недельку-другую переделывать.

Если вектор храннит именно объекты типа Foo, то никаких дополнительных действий не нужно.
Но похоже, что для сохранения функционала тебе нужен вектор указателей vector<Foo*> (

Там был такой класс, как Array. Судя с использования — массив указателей

), и тогда за временем жизни объектов придется следить самостоятельно. Ну или воспользоваться умными указателями.
Любите книгу — источник знаний (с) М.Горький
Re: Инициализация полей класса
От: jazzer Россия Skype: enerjazzer
Дата: 21.08.07 09:16
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Проблема такая. Переписываю старую прогу с старого билдера 5 на MS VS2005

OV>Там был такой класс, как Array. Судя с использования — массив указателей + плюс разные примочки(добавить/убрать элемент).
OV>Так как VC++ я не нашёл подобного класса, решил использовать вектор с stl.
OV>В общем имеем такой код
OV>
OV>class Foo
OV>{

OV>}

OV>class Bar
OV>{
OV>private:
OV>  vector<Foo> foo;
OV>}

OV>Bar *bar = new Bar();
OV>

OV>Вопрос. Нужно ли в конструкторе/деструкторе класса Bar какие то дополнительные манипуляции с классом Foo? На данный момент даже скомпилировать не могу свой код — там ещё на недельку-другую переделывать.

std::vector хранит элементы по значению.
Если тебе нужен массив именно указателей — можно использовать либо std::vector< boost::shared_ptr<Foo> >, либо std::vector< Foo* >, но в последнем случае придется удалять элементы вручную в деструкторе Bar.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:25
Оценка:
Здравствуйте, Bell, Вы писали:


B>Если вектор храннит именно объекты типа Foo, то никаких дополнительных действий не нужно.

Тогда меня устраивает
B>Но похоже, что для сохранения функционала тебе нужен вектор указателей vector<Foo*> (
B>

B>Там был такой класс, как Array. Судя с использования — массив указателей

B>), и тогда за временем жизни объектов придется следить самостоятельно. Ну или воспользоваться умными указателями.
поле приватно и для доступа к элементам используется такой код
Foo& getfoo(int index);

Вот я и думаю, как корректней вызовы переделать
мне кажеться где то так
return &foos.at(i);
хотя по поводу & не уверен
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[2]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:26
Оценка:
Здравствуйте, dip_2000, Вы писали:

_>Зависит от того, что вы хотите

_>По тому, что у вас написано — будет создан пустой вектор с количеством элементов равным 0.
Это меня устроит. Я потом сам туда элементов напхаю.
_>При уничтожении объекта Bar пямять занимаемая вектором будет особождена автоматически(разумеется если у вас там храняться указатели — память на которую они ссылаются будет потеряна).
Если деструкторы Foo будут вызваны, то он за собой подчистит всё как надо
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[3]: Инициализация полей класса
От: Bell Россия  
Дата: 21.08.07 09:32
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>поле приватно и для доступа к элементам используется такой код

OV>
OV>Foo& getfoo(int index);
OV>

OV>Вот я и думаю, как корректней вызовы переделать
OV>мне кажеться где то так
OV>return &foos.at(i);
OV>хотя по поводу & не уверен

Можно так:
return foos.at(i);

или так:
return foos[i];


В первом случае будет производится проверка на допустимость индекса, и если что-то не так, то at бросит исключение out_of_range.
Во втором случае никаких проверок не производится.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Инициализация полей класса
От: Erop Россия  
Дата: 21.08.07 09:36
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>хотя по поводу & не уверен


А нужно ли, чтобы адрес элемента этого вектора в течении его жизни не менялся?
Если это не нужно (грубо говоря для доступа всегда используется этот метод и указатель нигде не кэшируется), то всё и так получится, а если нужно, то не получится, так как вектор не гарантирует сохранение указателей на свои элементы.

Тогда надо будет таки хоранить указатели на объекты, и как-то управлять времени их жизни.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Инициализация полей класса
От: SuhanovSergey  
Дата: 21.08.07 09:36
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Здравствуйте, dip_2000, Вы писали:


_>>Зависит от того, что вы хотите

_>>По тому, что у вас написано — будет создан пустой вектор с количеством элементов равным 0.
OV>Это меня устроит. Я потом сам туда элементов напхаю.
_>>При уничтожении объекта Bar пямять занимаемая вектором будет особождена автоматически(разумеется если у вас там храняться указатели — память на которую они ссылаются будет потеряна).
OV>Если деструкторы Foo будут вызваны, то он за собой подчистит всё как надо
Я так понял Foo чем-то владеет. У него определены копирующий конструктор и оператор=()? Нужно учесть, что при хранении по значению, Foo должен уметь корректно копироваться. Так как по мере роста вектор выделяет новуя память, копирует старые элементы на нове место, а затем старые элементы удаляет.
Ещё нужно помнить, что при хранении по значению невозможно использовать полиморфизм. У вас этот Array содержал разностипные элементы?
Re[4]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:43
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:
SS>Я так понял Foo чем-то владеет. У него определены копирующий конструктор и оператор=()? Нужно учесть, что при хранении по значению, Foo должен уметь корректно копироваться.
Ну это не сложно написать.
SS>Так как по мере роста вектор выделяет новуя память, копирует старые элементы на нове место, а затем старые элементы удаляет.
Вектор при один раз при старте программы заполняется данными и дальше с него только читают/модифицируют поля вложенного класса.
SS>Ещё нужно помнить, что при хранении по значению невозможно использовать полиморфизм. У вас этот Array содержал разностипные элементы?
Нет. Исключительно однотипные элементы.
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[4]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:43
Оценка:
Здравствуйте, Bell, Вы писали:

B>В первом случае будет производится проверка на допустимость индекса, и если что-то не так, то at бросит исключение out_of_range.

B>Во втором случае никаких проверок не производится.
Вот об этом я и подумал, и решил, что на первое время исключения нада.
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[4]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 09:45
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, OdesitVadim, Вы писали:


E>А нужно ли, чтобы адрес элемента этого вектора в течении его жизни не менялся?

E>Если это не нужно (грубо говоря для доступа всегда используется этот метод и указатель нигде не кэшируется), то всё и так получится, а если нужно, то не получится, так как вектор не гарантирует сохранение указателей на свои элементы.

E>Тогда надо будет таки хоранить указатели на объекты, и как-то управлять времени их жизни.

Там всё мирно. Взяли объект, поменяли одно-два поля и забыли. Никто нигде не кеширует.
тоесть почти кругов вызов происходит где то так
bar.getfoos(i).somemetod();
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[5]: Инициализация полей класса
От: i-maverick Россия  
Дата: 21.08.07 14:58
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

B>>В первом случае будет производится проверка на допустимость индекса, и если что-то не так, то at бросит исключение out_of_range.

B>>Во втором случае никаких проверок не производится.
OV>Вот об этом я и подумал, и решил, что на первое время исключения нада.

Мне кажется, это некорректный подход. Это же не ассерты, которые только в дебаге проявляются. Это выбор решения. Либо ты используешь исключения, либо сам проверяешь границы массива.
Re[6]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 15:05
Оценка:
Здравствуйте, i-maverick, Вы писали:

IM>Здравствуйте, OdesitVadim, Вы писали:


B>>>В первом случае будет производится проверка на допустимость индекса, и если что-то не так, то at бросит исключение out_of_range.

B>>>Во втором случае никаких проверок не производится.
OV>>Вот об этом я и подумал, и решил, что на первое время исключения нада.

IM>Мне кажется, это некорректный подход. Это же не ассерты, которые только в дебаге проявляются. Это выбор решения. Либо ты используешь исключения, либо сам проверяешь границы массива.

Ну так на данный момент, так как код не мой и я не знаю, есть ли в нём потенциальные баги я делаю с at. На дальше, если проблем не будет, переправлю. Благое дело, благодаря структуре классов, это нужно делать в двух местах и всё (для двух разных классов). Хотя наверное может и оставлю at. Там за производительностью некуда гнаться.
В общем я ещё не определился
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[5]: Инициализация полей класса
От: Erop Россия  
Дата: 21.08.07 15:09
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Там всё мирно. Взяли объект, поменяли одно-два поля и забыли. Никто нигде не кеширует.

OV>тоесть почти кругов вызов происходит где то так
OV>bar.getfoos(i).somemetod();

Ну тогда наверное можно и как у тебя
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 21.08.07 15:16
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, OdesitVadim, Вы писали:


OV>>Там всё мирно. Взяли объект, поменяли одно-два поля и забыли. Никто нигде не кеширует.

OV>>тоесть почти кругов вызов происходит где то так
OV>>bar.getfoos(i).somemetod();

E>Ну тогда наверное можно и как у тебя

Тоесть, вектор гарантирует, что если я получил по ссылке обект с вектора и в нескольких строках ниже модифицирую этот объект (поля его), но не трогаю вектор, то плохого ничего не будет (вектор сам не перераспределит объекты в памяти и ссылка перестанет быть валидной)
Если в стандарте указания, после какие методы вектора безопасны, а какие нет по отношению к валидности ссылки?
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[7]: Инициализация полей класса
От: Erop Россия  
Дата: 21.08.07 19:11
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Если в стандарте указания, после какие методы вектора безопасны, а какие нет по отношению к валидности ссылки?

модифицирующие
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Инициализация полей класса
От: OdesitVadim Украина  
Дата: 22.08.07 06:49
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, OdesitVadim, Вы писали:


OV>>Если в стандарте указания, после какие методы вектора безопасны, а какие нет по отношению к валидности ссылки?

E>модифицирующие
Мда, ответ программиста. Ну это понятно, модифицирующие. Как говорил докдор: "Имя, сестра, имя!"
... << RSDN@Home 1.2.0 alpha rev. 719>>
Re[7]: Инициализация полей класса
От: Bell Россия  
Дата: 22.08.07 07:05
Оценка: 3 (1)
Здравствуйте, OdesitVadim, Вы писали:

OV>Здравствуйте, Erop, Вы писали:


E>>Здравствуйте, OdesitVadim, Вы писали:


OV>>>Там всё мирно. Взяли объект, поменяли одно-два поля и забыли. Никто нигде не кеширует.

OV>>>тоесть почти кругов вызов происходит где то так
OV>>>bar.getfoos(i).somemetod();

E>>Ну тогда наверное можно и как у тебя

OV>Тоесть, вектор гарантирует, что если я получил по ссылке обект с вектора и в нескольких строках ниже модифицирую этот объект (поля его), но не трогаю вектор, то плохого ничего не будет (вектор сам не перераспределит объекты в памяти и ссылка перестанет быть валидной)
Да, ничего плохого не случится.

OV>Если в стандарте указания, после какие методы вектора безопасны, а какие нет по отношению к валидности ссылки?

Конечно есть. Все модифицирующие методы вектора потенциально ведут к инвалидации ссылок/итераторов. Подробнее смотри 23.2.4.
Любите книгу — источник знаний (с) М.Горький
Re: Инициализация полей класса
От: alzt  
Дата: 22.08.07 07:49
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

OV>Проблема такая. Переписываю старую прогу с старого билдера 5 на MS VS2005

OV>Там был такой класс, как Array. Судя с использования — массив указателей + плюс разные примочки(добавить/убрать элемент).
OV>Так как VC++ я не нашёл подобного класса, решил использовать вектор с stl.
OV>В общем имеем такой код
OV>
OV>class Foo
OV>{

OV>}

OV>class Bar
OV>{
OV>private:
OV>  vector<Foo> foo;
OV>}

OV>Bar *bar = new Bar();
OV>

OV>Вопрос. Нужно ли в конструкторе/деструкторе класса Bar какие то дополнительные манипуляции с классом Foo? На данный момент даже скомпилировать не могу свой код — там ещё на недельку-другую переделывать.

Ничего не нужно. Всё сделается автоматически. Только, если вы будете использовать указатели vector<Foo*>, то не забывайте удалять каждый элемент в векторе.
Плюс, после закрывающейся скобки при определении класса надо ставить точку с запятой.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.