myVector.erase (myPtr) удаляют объект, на который указывает myPtr?

acceptsFirstMouse(for:) является методом на NSView, а не на NSViewController (или его суперклассах). Тот факт, что Swift не требовал от вас (и не позволил бы вам) использовать override в вашей функции, свидетельствует о том, что вы на самом деле не переопределяете метод. Кроме того, если бы вы поместили оператор print() в вашу попытку переопределения, вы бы увидели, что он никогда не вызывается.

Вам нужно использовать подкласс NSView и переопределить там метод.

Кроме того, относительно:

Когда вы выполняете 'функцию переопределения func acceptptsFirstMouse', которая возвращает true, представление должно действовать как первый респондент, даже если оно не в фокусе, верно? [ 1110]

Ну, не совсем. Это означает, что клики по представлению обрабатываются, даже если окно неактивно. Обратите внимание, что актуально состояние окна, а не вид. Представление в активном окне принимает щелчки независимо от того, является ли оно первым респондентом (и не обязательно первым респондентом, потому что оно щелкнуло). Кроме того, первый респондент имеет другие последствия, которые не связаны с кликами и не имеют ничего общего с acceptsFirstMouse(for:).

7
задан Sam 10 August 2014 в 09:27
поделиться

7 ответов

Да, Вы создали утечку памяти этим. станд.:: вектор и другие контейнеры просто удалят указатель, они не освободят память, на которую указывает указатель.

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

{ 
    boost::shared_ptr<foo> f(new foo);

    std::vector< boost::shared_ptr<foo> > v;
    v.push_back(f);
    v.erase(v.begin());
} /* if the last copy of foo goes out of scope, the memory is automatically freed */

Следующий стандарт C++ (названный C++ 1x и C++ 0x обычно) будет включать std::shared_ptr. Там, Вы также сможете использовать std::unique_ptr<T> который быстрее, поскольку это не позволяет копировать. Используя std::unique_ptr с контейнерами в C++ 0x подобен ptr_container библиотека в повышении.

8
ответ дан 6 December 2019 в 10:04
поделиться

Другая опция состоит в том, чтобы использовать Контейнеры Указателя Повышения. Они разработаны, чтобы сделать точно, что Вы хотите.

4
ответ дан 6 December 2019 в 10:04
поделиться

Кроме того, существует повышение:: контейнер ptr_vector.

Это знает, что содержит указатели, которыми это владеет, и таким образом автоматический удаляет их.

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

Foo *f = new Foo();
boost::ptr_vector<Foo>  vect;
vect.push_back(f);
// do stuff
vect.erase(f);
2
ответ дан 6 December 2019 в 10:04
поделиться

Для разъяснения, почему указатель не удален рассмотреть

std::vector<char const*> strings;
strings.push_back("hello");
strings.push_back("world");
// .erase should not call delete, pointers are to literals

std::vector<int*> arrays;
strings.push_back(new int[10]);
strings.push_back(new int[20]);
// .erase should call delete[] instead of delete

std::vector<unsigned char*> raw;
strings.push_back(malloc(1000));
strings.push_back(malloc(2000));
// .erase should call free() instead of delete

В целом, vector<T*>::erase не может предположить, как Вы избавились бы от a T*.

2
ответ дан 6 December 2019 в 10:04
поделиться

Это - определенно не ошибка указать на указатель в стандартный контейнер (это - ошибка сделать контейнер auto_ptr однако). Да, действительно необходимо явно удалить для освобождения памяти, на которую указывают отдельные элементы, или можно использовать один из интеллектуальных указателей повышения.

1
ответ дан 6 December 2019 в 10:04
поделиться

вектор удаляет данные, которые он содержит. Так как Ваш вектор содержит указатели, он только удаляет указатели, не данные они могут или не могут указать на.

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

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

vector<Foo> vect;
vect.push_back(Foo());
// do stuff
vect.erase(f);

Конечно, это предполагает, что Foo copyable, и что его конструктор копии не является слишком дорогим, но это избегает утечек памяти, и Вы не должны помнить удалять объект Foo. Другой подход должен был бы использовать интеллектуальные указатели (такие как shared_ptr Повышения), но Вам, возможно, не понадобится семантика указателя вообще, в этом случае простое решение является лучшим.

1
ответ дан 6 December 2019 в 10:04
поделиться

Контейнеры STL не освободят Вашу память. Лучший совет использует интеллектуальные указатели, зная что станд.:: auto_ptr не будет соответствовать внутренним контейнерам. Я рекомендовал бы повышение:: shared_ptr, или если у Вашего поставщика компилятора есть поддержка расширений TR1 (многие делают) можно использовать станд.:: tr1:: shared_ptr.

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

1
ответ дан 6 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

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