Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с функцией, добавление элемнта в контейнер 
V
    Опции темы
Riddik
Дата 1.6.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Приветsmile

Подскажите, как правильно написасть функцию:

есть абстрактный базовый класс Base и несколько производных от него,
eсть контейнер vector, содержащий указатели на базовый класс.

Код

std::vector<Base*> pb;


Функция нужна такая:
Код

void add(/*не знаю что*/ obj) {pb.push_back(new obj);}


Где obj - наследник базового класса Base.


PM MAIL   Вверх
mrbrooks
Дата 1.6.2009, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 19
Всего: 306



Riddik, а почему бы сразу не записывать в вектор производный класс? можно без указателя.
PM MAIL   Вверх
Riddik
Дата 1.6.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Нужно через функцию, потому что pb - это private - член другого класса.

Добавлено через 1 минуту и 48 секунд
И потому что в векторе будут разные производные классы
PM MAIL   Вверх
REZiaMIX
Дата 1.6.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: 1
Всего: 4



Код

void add(Base* obj) 
{
       pb.push_back(obj);
}

Так ?


--------------------
user posted image
PM MAIL   Вверх
Riddik
Дата 1.6.2009, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



REZiaMIX,  неа. Объект нужно создать, его не существует. нужно создать объект и поместить в вектор его адрес : push_back(new obj);
PM MAIL   Вверх
zim22
Дата 1.6.2009, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Riddik, что-то типа такого?
Код

class Base {
public:
  virtual ~Base() = 0;
};
Base::~Base() { }

class Derived1 : public Base {
public:
  Derived1(std::string n) :name(n) {  }
  ~Derived1() {}
private:
  std::string name;
};

class Derived2 : public Base {
public:
  ~Derived2() {}
};

template <typename T>
void add(std::vector<Base*> &vt, T &obj) {
  vt.push_back(new T(obj));
}
int _tmain(int argc, _TCHAR* argv[])
{
  std::vector<Base*> pb;
  add(pb, Derived1("parameters"));
  add(pb, Derived2());

    return 0;
}


Это сообщение отредактировал(а) zim22 - 1.6.2009, 17:35


--------------------
PM MAIL   Вверх
Riddik
Дата 1.6.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



zim22, спасибо smile.

Шаблонная функция мне и нужнаsmile 
PM MAIL   Вверх
Riddik
Дата 1.6.2009, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Только я не очень понял, почему так работает:

add(derived());

а так нет:

add(derived);

просто нет скобок после имени класса.

Компилятор выдаёт ошибку, что этот тип нельзя использовать в качестве выражения.

Если можно, объясните.
PM MAIL   Вверх
Riddik
Дата 1.6.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Ещё проблема. Объект создаётся дважды. При вызове функции создаётся объект, затем его копия передаётся в вектор - т.е. создаётся объект ещё раз.

Как этого избежать?

передача по ссылке ничего не меняет. 

Не знаю, какой делать конструктор копии, чтобы объект не создавался два раза.

Мне нужно, чтобы аргумент функции лишь говорил, какой класс положить в вектор.

Добавлено через 11 минут и 31 секунду
Вот код:
Код

template<class T> void add(T) {pb.push_back(new T);}


При вызове функции add(der());

вызывается конструктор der();
вызывается конструктор der();
вызывается деструктор ~der();

И после очистки вектора 

вызывается деструктор ~der();

Можно как-нибудь сделать, чтобы объект создавался только когда его адрес помещается в контейнер, один раз?
PM MAIL   Вверх
Rififi
Дата 2.6.2009, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 3
Всего: 36



Riddik, 
читать про паттерны Factory, Builder, Virtual Constructor, Prototype
PM MAIL   Вверх
zim22
Дата 2.6.2009, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Riddik @  1.6.2009,  22:02 Найти цитируемый пост)
 почему так работает:add(derived());а так нет:add(derived);

потому что в случае с круглыми скобками мы конструируем объект. и его тип уже вычисляется при передаче в функцию add
это аналогично следующей форме записи:
Код

add(pb, Derived2::Derived2());

без круглых скобок - не работает, т.к. форма записи не допустимая. smile

Rififi дело говорит. почитайте про паттерны.  smile 


--------------------
PM MAIL   Вверх
Riddik
Дата 2.6.2009, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Спасибо за помощьsmile
PM MAIL   Вверх
mes
Дата 2.6.2009, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Riddik @  1.6.2009,  21:27 Найти цитируемый пост)

Можно как-нибудь сделать, чтобы объект создавался только когда его адрес помещается в контейнер, один раз? 

Вы хотите чтоб создавался объект   по типу который Вы передаете   или    как копия объекта.
Если первое, то 
Код

template<class T> void add() {pb.push_back(new T());}
//
...add<Derived>();

Для второго случая  преимущество в том, что можно использовать любой необходимый конструктор (а потом просто снимется копия).

Но ваша конструкция мне внушает опасения, мне кажется Вы идете неправильным путем. Если не секрет зачем Вам такое понадобилось ?
Зачем нужно клонировать объект ?

Это сообщение отредактировал(а) mes - 2.6.2009, 09:41


--------------------
PM MAIL WWW   Вверх
Riddik
Дата 2.6.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



mes, мне нужно это: "создавался объект   по типу который Вы передаете"


Как раз копия мне не нужна!

Спасибо! Вы очень помогли! 
PM MAIL   Вверх
Riddik
Дата 2.6.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 598
Регистрация: 2.12.2006

Репутация: нет
Всего: нет



Ругается на 
Код

add<Derived>();


Пишет 'Derived' : illegal use of this type as en expression, не пойму почему. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.2442 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.