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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> По поводу наследования 
:(
    Опции темы
Salatovec
Дата 25.9.2013, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Доброго всем времени суток, столкнулся с такой проблемой - вот код:

Код

class CFigure
{
public:
    virtual void Draw(void) = 0;
};

class CBox : public CFigure
{
public:
    virtual void Draw(void);
};

class CCone : public CFigure
{
public:
    virtual void Draw(void);
};

int main()
{
    CFigure *figures[2];
    
    figures[0] = new CBox;
    figures[1] = new CCone;

    figures[0].Draw();
    figures[1].Draw();

    delete figures[];

    return 0;
}


Можно ли при сохранении структуры классов создать массив фигур без указателей и конструкций аля new-delete?

Заранее спасибо за помощь!

PM MAIL   Вверх
Earnest
Дата 25.9.2013, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Без указателей в один массив разные типы загнать нельзя. А вот без delete обойтись вполне можно. Используй умные указатели, например из буста. Насчет new - если есть желание и смысл заморачиваться, можно какую-нибудь фабрику организовать. Но где-то все равно будет new, естественно.


--------------------
...
PM   Вверх
Salatovec
Дата 25.9.2013, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Earnest, спасибо, с этим моментом понял. Тогда попробую с другой стороны зайти. При использовании такой структуры проблема возникла при реализации возможности удаления из массива выборочного элемента. Например:

Код

int main()
{
    CFigure *figures[4];
    
    figures[0] = new CBox;
    figures[1] = new CCone;
    figures[2] = new CBox;
    figures[3] = new CCone;

    delete figures[1];

    ....
}


А как дальше? Нужно же поменять размер массива. Переместить элементы 2 и 3 на место 1 и 2 соответственно. Это я победить так и не смог.
PM MAIL   Вверх
Guinness
Дата 25.9.2013, 11:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



PM MAIL   Вверх
vinter
Дата 25.9.2013, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



+ std::unique_ptr хранить в векторе, а не голые указатели.


--------------------
Мой блог
PM MAIL WWW   Вверх
Salatovec
Дата 25.9.2013, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Guinness, а можно небольшой примерчик использования?

vinter, это не буст случаем?
PM MAIL   Вверх
vinter
Дата 25.9.2013, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Код

#include <vector>
#include <memory>
#include <algorithm>
int main()
{
    std::vector<std::unique_ptr<CFigure>> figures;
    
    figures.emplace_back(new CBox);
    figures.emplace_back(new CCone);
    figures.emplace_back(new CBox);
    figures.emplace_back(new CCone);
    figures.erase(std::begin(figures) + 1);
    ....
}

Это не буст, это стандартный C++. Правда требует более-менее свежего компилятора.
P.S. я не собирал пример.

Это сообщение отредактировал(а) vinter - 25.9.2013, 12:48


--------------------
Мой блог
PM MAIL WWW   Вверх
Guinness
Дата 25.9.2013, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(vinter @  25.9.2013,  13:17 Найти цитируемый пост)
std::unique_ptr 

Точно? Это же аналог auto_ptr с некоторыми улучшениями? А такой тип указателей не рекомендуется хранить в контейнерах. Лучше, std::shared_ptr( если C++11 ) или boost::shared_ptr( в более ранних версиях ).
Цитата(Salatovec @  25.9.2013,  13:37 Найти цитируемый пост)
а можно небольшой примерчик использования?

Я же вроде ссылку дал на вики с примером. Или какой-то конкретный момент непонятен?
PM MAIL   Вверх
vinter
Дата 25.9.2013, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата

Точно? Это же аналог auto_ptr с некоторыми улучшениями? А такой тип указателей не рекомендуется хранить в контейнерах

Это то, чем должен был быть auto_ptr, но так и не стал в связи с отсутствием понятия "перемещение" в ранних версиях стандарта. Насчёт "не рекомендуется использовать": впервые слышу, какие аргументы? std::shared_ptr накладывает определенные накладные расходы, которые в данном случае не нужны. Если нет потребности в std::shared_ptr его использования стоит избегать, это не бесплатная сущность. В отличие от std::unique_ptr.


--------------------
Мой блог
PM MAIL WWW   Вверх
Guinness
Дата 25.9.2013, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(vinter @  25.9.2013,  14:27 Найти цитируемый пост)
Насчёт "не рекомендуется использовать": впервые слышу, какие аргументы?

auto_ptr ведет себя вот так:
Код

    auto_ptr<int> p1( new int(10) );
    auto_ptr<int> p2;
    p2 = p1; // p1 - null_ptr, p2 - указывает на int(10)

Судя, по описанию unique_ptr он ведет себя схожим образом:
Код

[url=http://www.cplusplus.com/reference/memory/unique_ptr/]Ссылка[/url]
unique_ptr objects own their pointer uniquely: no other facility shall take care of deleting the object, and thus no other managed
pointer should point to its managed object, since as soon as they have to, unique_ptr objects delete their managed object
without taking into account whether other pointers still point to the same object or not, and thus leaving any other pointers that
point there as pointing to an invalid location.

[url=http://www.cplusplus.com/reference/memory/unique_ptr/operator=/]Ссылка[/url]
unique_ptr assignment
The object acquires the ownership of x's content, including both the stored pointer and the stored deleter 
(along with the responsibility of deleting the object at some point). Any object owned by the unique_ptr
object before the call is deleted (as if unique_ptr's destructor was called).


Может я чего-то не допонял или не так перевел? Но вызов foreach для вектора как показано ниже приведет к печальным последствиям:
Код

vector< unique_ptr<Object> > v;
...
for_each( v.begin(), v.end(), func ); // где func - принимает объект по значению

Или я не прав?

Это сообщение отредактировал(а) Guinness - 25.9.2013, 14:05
PM MAIL   Вверх
azesmcar
Дата 25.9.2013, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Guinness @  25.9.2013,  14:04 Найти цитируемый пост)
Или я не прав?

 smile 
std::unique_ptr как раз таки можно хранить в контейнерах.

Добавлено через 1 минуту и 45 секунд
http://en.cppreference.com/w/cpp/memory/unique_ptr
Typical uses of std::unique_ptr include:
  • providing exception safety to classes and functions that handle objects with dynamic lifetime, by guaranteeing deletion on both normal exit and exit through exception
  • passing ownership of uniquely-owned objects with dynamic lifetime into functions
  • acquiring ownership of uniquely-owned objects with dynamic lifetime from functions
  • as the element type in move-aware containers, such as std::vector, which hold pointers to dynamically-allocated objects (e.g. if polymorphic behavior is desired)

PM   Вверх
Guinness
Дата 25.9.2013, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(azesmcar @  25.9.2013,  15:09 Найти цитируемый пост)
std::unique_ptr как раз таки можно хранить в контейнерах.

Так, я там проглядел, но у unique_ptr есть следующие объявления:
Код

copy (deleted!) (9) unique_ptr (const unique_ptr&) = delete;
copy assignment (deleted!) (4) unique_ptr& operator= (const unique_ptr&) = delete;

Т.е. копирование запрещено как таковое. Получается, что мой пример с for_each мне выкинет ошибку на этапе компиляции? А контейнеры в любом случае будут возвращать ссылку на unique_ptr. Получается избегаем проблем связанных с auto_ptr.
PM MAIL   Вверх
vinter
Дата 25.9.2013, 14:21 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата

Судя, по описанию unique_ptr он ведет себя схожим образом:

Нет, он не имеет конструктора копирования, только конструктор перемещения, что делает его тем, чем auto_ptr так и не стал.
Вы не можете его использовать неправильно неявно, в отличие от auto_ptr
Цитата

Или я не прав?

Не правы, приведённые пример просто не соберется, по причине, которая приведена выше. 
А вот так соберётся:
Код

for_each( v.begin(), v.end(), [](unique_ptr<int>&){});

Чтобы Ваш пример собирался и работал for_each должен выглядеть как-то так:
Код

void for_each(Iter begin, Iter end, Func func)
{
     for(auto it = begin; it != end; ++it)
         func(std::move(*it));
}

Само собой, никакого std::move в стандартной версии нет ибо это бы ломало контейнеры. А так контейнеры вполне хорошо работают с объектами, которые не могут быть скопированы, а могут лишь быть перемещёнными.


--------------------
Мой блог
PM MAIL WWW   Вверх
Guinness
Дата 25.9.2013, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(vinter @  25.9.2013,  15:21 Найти цитируемый пост)
Чтобы Ваш пример собирался и работал for_each должен выглядеть как-то так:

Ну да, либо функция должна принимать ссылку на unique_ptr.
PM MAIL   Вверх
Salatovec
Дата 25.9.2013, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



vinter, спасибо за пример, попробую в свободное от работы время.

Цитата(Guinness @  25.9.2013,  13:20 Найти цитируемый пост)
Я же вроде ссылку дал на вики с примером. Или какой-то конкретный момент непонятен? 

Не заметил ссылку, спасибо.

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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