Объекты должны удалить себя в C++?

Можно было бы использовать include_tasks. Смотрите подсказку ниже.

tasks:
  - include_tasks: test.yml
    loop: "{{ php.versions }}"
    loop_control:
      loop_var: php_ver

.

> cat test.yml
- debug: msg="{{ lookup('dict', php_ver).key }}"
- debug: msg="{{ item }}"
  loop: "{{ lookup('dict', php_ver).value }}"

Вот книга игр

> cat test-31.yml
---
- hosts: localhost
  gather_facts: no
  vars:
    php:
      versions:
        - 7.2:
            - cli
            - fpm
            - curl
            - mysql
            - pdo
            - zip
            - xml
            - gd
            - mbstring
            - tokenizer
            - ctype
            - json
        - 7.3:
            - cli
            - fpm
            - curl
            - mysql
            - pdo
            - zip
            - xml
            - gd
            - mbstring
            - tokenizer
            - ctype
            - json
  tasks:
    - include_tasks: test.yml
      loop: "{{ php.versions }}"
      loop_control:
        loop_var: php_ver

Вот выход

> ansible-playbook test-31.yml | grep msg
    "msg": "7.2"
    "msg": "cli"
    "msg": "fpm"
    "msg": "curl"
    "msg": "mysql"
    "msg": "pdo"
    "msg": "zip"
    "msg": "xml"
    "msg": "gd"
    "msg": "mbstring"
    "msg": "tokenizer"
    "msg": "ctype"
    "msg": "json"
    "msg": "7.3"
    "msg": "cli"
    "msg": "fpm"
    "msg": "curl"
    "msg": "mysql"
    "msg": "pdo"
    "msg": "zip"
    "msg": "xml"
    "msg": "gd"
    "msg": "mbstring"
    "msg": "tokenizer"
    "msg": "ctype"
    "msg": "json"
24
задан Sam 24 October 2014 в 18:23
поделиться

11 ответов

Проблема с этим состоит в том, что Вы действительно создаете неявную связь между объектом и Мировым классом.

, Если я пытаюсь назвать Обновление () вне Мирового класса, что происходит? Я мог бы закончить с объектом, удаляемым, и я не знаю почему. Кажется, что обязанности плохо перепутаны. Это собирается вызвать проблемы момент, Вы используете класс Огня в новой ситуации, о которой Вы не думали при написании этого кода. Что происходит, если объект должен быть удален больше чем из одного места? Возможно, это должно быть удалено и из мира, текущей карты и из материально-технических ресурсов игрока? Ваша функция Обновления удалит его из мира и затем удалит объект, и в следующий раз, когда карта или материально-технические ресурсы пытаются получить доступ к объекту, Плохие Вещи Происходят.

В целом, я сказал бы, что это очень неинтуитивно для Обновления () функция для удаления объекта, который это обновляет. Я также сказал бы, что это неинтуитивно для объекта удалить себя. Объект должен более вероятно иметь некоторый способ для увольнения события, говоря, что это закончило гореть, и любой заинтересовал, может теперь действовать на это. Например, путем удаления его из мира. Для удаления его думайте с точки зрения владения.

, Кто владеет объектом? Мир? Это означает, что один только мир добирается для решения, когда объект умирает. Это прекрасно, пока ссылка в мире на объект собирается пережить другой ссылки на него. Вы думаете объект, собственный сам? Что это даже означает? Объект должен быть удален, когда объект больше не существует? Не имеет смысла.

, Но если нет никакого ясно определенного единственного владельца, реализуйте совместно использованное владение, например, с помощью интеллектуального указателя, реализовав подсчет ссылок, такой как boost::shared_ptr

, Но имея функцию членства на самом объекте, который является hardcoded для удаления объекта от один определенный список, существует ли он там, и существует ли он также в любом другом списке, и также удалите сам объект, независимо от которого существуют ссылки на него, плохая идея.

20
ответ дан jalf 28 November 2019 в 22:22
поделиться

Вы сделали Update виртуальная функция, предположив, что производные классы могут переопределить реализацию Update. Это представляет два больших риска.

1.) Переопределенная реализация может не забыть делать World.Remove, но может забыть delete this. Память пропущена.

2.) Переопределенная реализация называет базовый класс Update, который делает delete this, но затем возобновляет больше работы, но недопустимый этот-указатель.

Рассматривают этот пример:

class WizardsFire: public Fire
{
public:
    virtual void Update()
    {
        Fire::Update();  // May delete the this-object!
        RegenerateMana(this.ManaCost); // this is now invaild!  GPF!
    }
}
30
ответ дан abelenky 28 November 2019 в 22:22
поделиться

Нет ничего действительно неправильно с объектами, удаляя себя в C++, большинство реализаций подсчета ссылок будет использовать что-то подобное. Однако это считается немного тайной техникой, и необходимо будет не спускать действительно близких глаз с проблем владения.

6
ответ дан 1800 INFORMATION 28 November 2019 в 22:22
поделиться

Удаление перестанет работать и может разрушить программу, если объект был не выделен и создан с новым. Эта конструкция будет препятствовать тому, чтобы Вы инстанцировали класса на стеке или статически. В Вашем случае Вы, кажется, используете некоторую схему выделения. Если Вы придерживаетесь этого, это могло бы быть безопасно. Я, конечно, не сделал бы этого, все же.

6
ответ дан Rob deFriesse 28 November 2019 в 22:22
поделиться

Я предпочитаю более строгую модель владения. Мир должен владеть объектами в нем и быть ответственен за чистку их. Или имейте мир, удаляют, делают это или имеют обновление (или другая функция) возвращают значение, которое указывает, что объект должен быть удален.

я также предполагаю, что в этом типе шаблона, Вы собираетесь хотеть к подсчету ссылок свои объекты постараться не заканчиваться с висячими указателями.

5
ответ дан hacken 28 November 2019 в 22:22
поделиться

Это, конечно, работает на объекты, созданные new и когда вызывающей стороне Update лет правильно сообщают о том поведении. Но я избежал бы его. В Вашем случае владение ясно в Мире, таким образом, я заставил бы мир удалить его. Объект не создает себя, я думаю, что он не должен также удалять себя. Может быть очень удивительным, если Вы называете функциональное "Обновление" на своем объекте, но затем внезапно, что объект больше не является существующим без Мира, делающего ничто из себя (кроме Удаления его из его списка - но в другом кадре! Код, называя Обновление на объекте не заметит это).

Некоторые идеи об этом

  1. Добавляют список ссылок на объект на Мир. Каждый объект в том списке находится на рассмотрении для удаления. Это - общая техника и используется в wxWidgets для окон верхнего уровня, которые закрылись, но могут все еще получить сообщения. Во время простоя, когда все сообщения обрабатываются, обрабатывается незаконченный список, и объекты удалены. Я полагаю, что QT следует за подобной техникой.
  2. Говорят миру, что объект хочет быть удаленным. Миру правильно сообщат и будет заботиться о любом материале, который должен быть сделан. Что-то как deleteObject(Object&), возможно.
  3. Добавляют shouldBeDeleted функция к каждому объекту, который возвращает true, если объект хочет быть удаленным его владельцем.

я предпочел бы опцию 3. Мир назвал бы Обновление. И после этого, это смотрит, должен ли объект быть удален и может сделать так - или если это желает, это помнит, что факт путем добавления, что объект к незаконченному удалению перечисляет вручную.

Это - боль в заднице, когда Вы не можете быть уверены когда и если не смочь к функциям доступа и данным объекта. Например, в wxWidgets, существует wxThread класс, который может работать в двух режимах. Один из этих режимов (названный "съемным") - то, что, если его основная функция возвращается (и ресурсы потока должен быть выпущен), это удаляет себя (для освобождения памяти, занятой объектом wxThread) вместо того, чтобы ожидать владельца объекта потока назвать функция соединения или ожидание. Однако это вызывает сильную головную боль. Вы никогда не можете вызывать функции на нем, потому что это, возможно, было завершено при любых обстоятельствах, и у Вас не может быть созданного не с новым. Некоторые люди сказали мне, что им очень не нравится то поведение его.

сам удаление ссылки считаемый объект пахнет, по моему скромному мнению. Давайте сравним:

// bitmap owns the data. Bitmap keeps a pointer to BitmapData, which
// is shared by multiple Bitmap instances. 
class Bitmap {
    ~Bitmap() {
        if(bmp->dec_refcount() == 0) {
            // count drops to zero => remove 
            // ref-counted object. 
            delete bmp;
        }
    }
    BitmapData *bmp;
};

class BitmapData {
    int dec_refcount();
    int inc_refcount();

};

Сравнивают это с самоудалением refcounted объекты:

class Bitmap {
    ~Bitmap() {
        bmp->dec_refcount();
    }
    BitmapData *bmp;
};

class BitmapData {
    int dec_refcount() {
        int newCount = --count;
        if(newCount == 0) {
            delete this;
        }
        return newCount;
    }
    int inc_refcount();
};

я думаю, что первое настолько более хорошо, и я верю хорошо разработанной ссылке, которую считаемые объекты делают не , действительно "удаляют это", потому что она увеличивает связь: класс с помощью ссылки рассчитал, данные должны знать и помнить, о котором данные удаляют себя как побочный эффект постепенного уменьшения подсчета ссылок. Отметьте, как "bmp" становится возможно висячим указателем в деструкторе ~Bitmap. Возможно, не выполнение, которые "удаляют это", намного более хорошо здесь.

Ответ на подобный вопрос , "Каково использование, удаляет это"

5
ответ дан Community 28 November 2019 в 22:22
поделиться

Это - реализация подсчета довольно общей ссылки, и я использовал это успешно прежде.

Однако я также видел, что он отказывает. Мне бы хотелось помнить обстоятельства за катастрофический отказ. @abelenky является одним местом, которое я видел, что он разрушает.

Это, возможно, было, где Вы далее разделяете на подклассы Fire, но не удаетесь создать виртуальный деструктор (см. ниже). Когда у Вас не будет виртуального деструктора, эти Update(), функция будет звонить ~Fire() вместо соответствующего деструктора ~Flame().

class Fire : Object
{
public:
    virtual void Update()
    {
        if(age > burnTime)
        {
            world.Remove(this);
            delete this; //Make sure this is a virtual destructor.
        }
    }
};

class Flame: public Fire
{
private: 
    int somevariable;
};
2
ответ дан Community 28 November 2019 в 22:22
поделиться

Другие упомянули, что проблемы с "удаляют это". Короче говоря, так как "Мир" справляется с созданием Огня, это должно также справиться со своим удалением.

Еще одна проблема состоит в том, если мир заканчивается огнем, все еще горящим. Если это - единственный механизм, через который может быть уничтожен огонь, то Вы могли закончить с огнем мусора или висячей строкой.

Для семантики Вы хотите, у меня был бы "активный" или "живой" флаг в Вашем классе "Огня" (или Объект если применимо). Затем мир при случае проверил бы свои материально-технические ресурсы объектов и избавился бы от, которые больше не активны.

-

Еще одно примечание - то, что Ваш код, как записано имеет Огонь, конфиденциально наследовавшийся Объекту, так как это - значение по умолчанию, даже при том, что это намного менее распространено, чем общественность inheiritance. Необходимо, вероятно, сделать вид из наследования явным, и я подозреваю, что Вы действительно хотите общественность inheritiance.

2
ответ дан JohnMcG 28 November 2019 в 22:22
поделиться

Это обычно не хорошая идея сделать, "удаляют это" если необходимый или используемый очень простым способом. В Вашем случае похоже, что Мир может просто удалить объект, когда это удалено, если нет другие зависимости, которые мы не видим (в этом случае Ваш удалять вызов, вызовет ошибки, так как они не уведомляются). Хранение владения вне Вашего объекта позволяет Вашему объекту лучше инкапсулироваться и более стабильное: объект не станет недопустимым в какой-то момент просто, потому что он принял решение удалить себя.

1
ответ дан Ron Warholic 28 November 2019 в 22:22
поделиться

Я не делаю этого, там что-либо по сути неправильно с объектом, удаляя себя, но другой возможный метод должен был бы иметь мир быть ответственным за удаление объектов как часть:: Удалите (предполагающий, что все Удаленные объекты были также удалены.)

0
ответ дан Yes - that Jake. 28 November 2019 в 22:22
поделиться

удалите это очень опасно. НЕТ ничего "неправильно" с ним. Это законно. Но существует столько вещей, которые могут пойти не так, как надо, когда Вы используете его, что это должно использоваться экономно.

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

В большинстве случаев, я думаю, что объектным временем жизни должен управлять тот же объект, который создает его. Это просто помогает знать, где разрушение происходит.

0
ответ дан Erik Funkenbusch 28 November 2019 в 22:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: