Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 5.00
-THE_MASTER666-
Заблокирован
#1

Можно ли удалить объект экземпляра класса из самого себя? - C++

18.11.2014, 15:10. Просмотров 2833. Ответов 67
Метки нет (Все метки)

Привет!
Допустим:
C++
1
2
3
4
5
6
7
8
9
10
class TEST
{
public:
    TEST();
    ~TEST();
    void DelMe()
    {
        //DEL ME :-)
    }
};
Вот в теле функции DelMe можно как то удалить собственный экземпляр класса? То есть удалить самого себя из себя?

Добавлено через 4 минуты
Вот так вроде работает, но как - то это ..... Так память нормально освобождается?
C++
1
2
3
4
  void DelMe()
    {
        delete this;
    }
деструктор вроде вызывается

Добавлено через 4 минуты
Нашёл себе методичку: http://www.parashift.com/c++-faq-lite/delete-this.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2014, 15:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Можно ли удалить объект экземпляра класса из самого себя? (C++):

Удаление экземпляра класса в функции самого класса (Ошибка при отладке) - C++
Допустим, у нас есть класс Buffer, который хранит в себе указатель на класс некоторой матрицы и количество этих указателей refcounter ...

как сделать чтобы объект производного класса сам себя добавлял в список или массив указателей базового класса? - C++
я хотел так, но программа просто падает void Student::add(Base** head) { cout << "I here" << endl; this->setName(); //все...

Можно ли заставить класс записывать самого себя в файл? - C++
то есть class A{ int q,w,e; bool Write(); }; main(){ A a1; a1.write();// и он записывает сам себя в файл, не...

Можно ли получить ссылку на экземпляр класса по полю этого экземпляра - C++
схематично код такой - class A { static void staticMethodA(SomeClass* memberA); SomeClass* memberA; } void...

Создание нового экземпляра дочернего класса из экземпляра базового - C++
Всем привет! Извиняюсь, если вопрос глупый, но что-то не смог найти конкретный ответ на него... У меня есть несколько классов: все они...

При создании экземпляра класса, создается 2 экземпляра вместо 1 - C++
Подсчет экземпляров ведется с помощью статического члена num_dogs, который во всех трех конструкторах (1. по умолчанию, 2. со всеми...

67
-THE_MASTER666-
Заблокирован
18.11.2014, 16:31  [ТС] #16
Цитата Сообщение от 0x10 Посмотреть сообщение
У него нет ни конструктора копирования, ни оператора присваивания.
А..понял
Цитата Сообщение от 0x10 Посмотреть сообщение
Т.е. его можно только переместить.
Ну я же могу его переместить его сразу в два потока?
0
0x10
2465 / 1637 / 241
Регистрация: 24.11.2012
Сообщений: 4,040
18.11.2014, 16:32 #17
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Ну я же могу его переместить его сразу в два потока?
Очевидно, нет.
1
-THE_MASTER666-
Заблокирован
19.11.2014, 11:33  [ТС] #18
Цитата Сообщение от 0x10 Посмотреть сообщение
Очевидно, нет.
Ладно, всё понял - спасибо

Добавлено через 18 часов 54 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
-THE_MASTER666-, Используйте shared_ptr.
А можно ли этот shared_ptr передавать из одной DLL в другую?
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
19.11.2014, 12:20 #19
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
А можно ли этот shared_ptr передавать из одной DLL в другую?
Не отвечу точно. Предлагаю почитать: http://stackoverflow.com/questions/1...dll-interfaces
1
-THE_MASTER666-
Заблокирован
19.11.2014, 13:00  [ТС] #20
Цитата Сообщение от ForEveR Посмотреть сообщение
Не отвечу точно. Предлагаю почитать
Чё то я запутался
В общем попробовал поиграть с QSharedPointer, всё нормально передаётся из DLL в EXE и деструктор корректно вызывается после потери последней ссылки при выходе за скоп.
Полагаю, что вообще в Qt с передачей данных DLL - EXE , как впрочем и использование шаблонов в DLL, всё тип топ, т.к. весь Qt построен на идеоме Pimpl, там повсюду private классы
В общем раз работает, то темя исчерпана, всё равно я на Qt пишу

Добавлено через 1 минуту

Не по теме:

ForEveR, нет какого - нибуть линка на статейку по собственному очень быстрому алокатору памяти?

0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
19.11.2014, 13:17 #21
-THE_MASTER666-, Нет, очень быстрый неслабо так растяжимое понятие. Можно посмотреть на http://www.boost.org/doc/libs/1_55_0...tml/index.html
1
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
19.11.2014, 17:18 #22
Цитата Сообщение от ForEveR Посмотреть сообщение
А можно ли этот shared_ptr передавать из одной DLL в другую?
Можно(*), если deleter будет из той же dll, где выделяли память под объект.
Тоже самое с QSharedPointer. Но в частном случае может работать, если все собирается одним компилятором с одними и теми же настройками (впрочем эта тема уже раскрыта в твоих предыдущих вопросах). Если ты не собираешься менять компилятор или передавать кому-то свою dll в скомпилированном виде, то можешь действительно на это забить и писать как писал.

______
* в пределах одной версии ABI. Если, скажем, dll написана в mingw, то заюзать ее в таком виде из VS не получится, из-за разных соглашений об ABI.
0
-THE_MASTER666-
Заблокирован
19.11.2014, 18:39  [ТС] #23
Цитата Сообщение от DrOffset Посмотреть сообщение
Если ты не собираешься менять компилятор или передавать кому-то свою dll в скомпилированном виде, то можешь действительно на это забить и писать как писал.
Как раз собираюсь.
Так в чём тут подвох - то?
Вот создал я объект QSharedPointer в одной DLL и инициализировал его каким - то объектом:
C++
1
QSharedPointer<MyObject> so(new MyObject);
Функция, где был создан этот объект возвращает QSharedPointer<MyObject>:
C++
1
QSharedPointer<MyObject> GetData();
Я его создал и вернул, то есть return so; - то есть объект QSharedPointer скопировался, а вызывал я эту ГЕТ ДАТА их ЕХЕ, то там у меня:
C++
1
QSharedPointer<MyObject> exe_SO = module->GetData();
, после выхода за SCOPE, объект удалился. Вроде всё тип топ, но кто его удалил и из какого контекста? DLL-ка вызвала deleter или EXE?

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Можно(*), если deleter будет из той же dll, где выделяли память под объект.
Или имеется ввиду, что если я создал QSharedPointer<MyObject> в DLL и потерял на QSharedPointer<MyObject> указатель, выйдя из функции создания, но успел передать его в ЕХЕ и когда в ЕХЕ я выйду за SCOPE, то удалит его ЕХЕ, а не DLL и так нельзя? То есть нельзя терять указатель на QSharedPointer<MyObject> в DLL? Но какой тогда в нём толк ититская тонна ?
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
19.11.2014, 18:56 #24
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
DLL-ка вызвала deleter или EXE?
Вот смотри сюда.
Смотри 337 строку. Видишь там delete?
Этот файл будет независимо вкомпилен и в dll и в exe при использовании QSharedPtr. Все хорошо пока exe и dll делят общий runtime, а если нет, или же это разные компиляторы (версии), либо разные настройки (debug\release и т.п.), то это будут разные delete.
Решить проблему с разными runtime можно используя custom deleter у QSharedPtr (см. тут), но это все равно не решит проблему разных ABI, если кто-то захочет твою dll, написанную, скажем, в MinGW использовать в VS. Но эта проблема более комплексная, т.к. затрагивает и Qt (у нее весь интерфейс на С++, а значит версия Qt для VS в любом случае не подойдет для MinGW).

Добавлено через 51 секунду
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
То есть нельзя терять указатель на QSharedPointer<MyObject> в DLL? Но какой тогда в нём толк ититская тонна ?
Можно терять, если внутри сохраняется указатель на правильную удаляющую функцию.
1
-THE_MASTER666-
Заблокирован
19.11.2014, 19:49  [ТС] #25
Цитата Сообщение от DrOffset Посмотреть сообщение
Можно терять, если внутри сохраняется указатель на правильную удаляющую функцию.
Ну где внутри то? В моём случае в классе MyObj? А что именно туда сохранить нужно, вот конкретно, можно хоть пару строк примерЧеГа ?
То есть в любом случае, если я создал QSharedPointer в DLL, и жду его авто удаления при выходе за скоп уже в ЕХЕ, мне надо будет в любом случае что - то вручную вызывать? Тогда зачем вообще нужен этот шаред пойнтер ...
Можно хоть совсем чуть чуть сорца в студию


Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Все хорошо пока exe и dll делят общий runtime
Что буквально имеется ввиду? Что значит делят рантайм?

Добавлено через 36 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
или же это разные компиляторы (версии)
Допустим в случае сборки VS и GCC уже будут проблемы?

Добавлено через 6 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
либо разные настройки (debug\release и т.п.)
Не, ну это то понятно, я обычно к дебажным dll-кам добавляю "d".
Цитата Сообщение от DrOffset Посмотреть сообщение
или же это разные компиляторы (версии)
А почему разные версии компилятора влиять? Я чёт не пойму, вот допустим я собрал DLL в VisualStudio2010 и что, я не смогу её подключить в собранном виде к проекту в VS2013? Ну вот допустим все DLL-ки для DirectX работают на любой студии.
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
19.11.2014, 20:09 #26
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Что буквально имеется ввиду? Что значит делят рантайм?
Я про это рассказывал уж в одной из предыдущих твоих тем. С++ Runtime - это библиотека времени исполнения, в ней находится в том числе реализация стандартного С++ аллокатора. В VS они называются msvcr***, у каждой версии VS своя версия С++ runtime. Отсюда весь этот разнообразный набор пакетов ms redist.

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Я чёт не пойму, вот допустим я собрал DLL в VisualStudio2010 и что, я не смогу её подключить в собранном виде к проекту в VS2013?
Можешь. Но могут быть проблемы, о которых говорилось выше и в предыдущих твоих темах.

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Допустим в случае сборки VS и GCC уже будут проблемы?
Вообще я имел в виду разные версии одного и того же компилятора.
В случае GCC и VS, возникают гораздо более серьезные проблемы, т.к С++ ABI у них несовместимо, следовательно ты даже скомпилировать ничего не сможешь до тех пор, пока используешь интерфейсы в стиле С++ (но сможешь, если использовать С).

Добавлено через 3 минуты
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Ну вот допустим все DLL-ки для DirectX работают на любой студии.
Работают. Потому что написаны правильно. Ты объекты, которые выделяешь там, не сам же удаляешь. Ты используешь метод Release, который реализован на стороне dll directx. Обо всем этом тебе уже в которой теме толкуют
Вот отрывок примера из MSDN:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    IDXGIFactory1* dxgiFactory = nullptr; 
    { 
        IDXGIDevice* dxgiDevice = nullptr; 
        hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); 
        if (SUCCEEDED(hr)) 
        { 
            IDXGIAdapter* adapter = nullptr; 
            hr = dxgiDevice->GetAdapter(&adapter); 
            if (SUCCEEDED(hr)) 
            { 
                hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); 
                adapter->Release();  // <<< ВНИМАНИЕ СЮДА
            } 
            dxgiDevice->Release(); // <<< ВНИМАНИЕ СЮДА
        } 
    }
Добавлено через 4 минуты
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Ну где внутри то?
Внутри объекта QSharedPtr. Я тебе там выше ссылку дал на конструктор, который позволяет это обеспечить.

Добавлено через 42 секунды
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
жду его авто удаления при выходе за скоп уже в ЕХЕ, мне надо будет в любом случае что - то вручную вызывать?
Не надо будет ничего вызывать вручную.

Добавлено через 28 секунд
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Можно хоть совсем чуть чуть сорца в студию
В ссылке, которую я дал на доку, был пример.
1
-THE_MASTER666-
Заблокирован
19.11.2014, 20:18  [ТС] #27
Цитата Сообщение от DrOffset Посмотреть сообщение
у каждой версии VS своя версия С++ runtime.
Ну и что, что своя, обычно в Windows установлены рантаймы сразу для многих версий.
Я вообще не любитель оставлять рантаймы наружу, ведь я же в студии эти рантаймы статической линковкой DLL могу внутрь загнать и тогда по идее проблем же не должно быть?

Цитата Сообщение от DrOffset Посмотреть сообщение
Можешь. Но могут быть проблемы, о которых говорилось выше и в предыдущих твоих темах.
А что каждая версия рантаймов обратно не совместима что ли? А...забей

Цитата Сообщение от DrOffset Посмотреть сообщение
В случае GCC и VS, возникают гораздо более серьезные проблемы
Не, ну тут я погорячился, т.к. VS ты под линукс не соберёшь, ровно как и GCC под Windows, по этому понятно что "o" и "dll" одновременно мешать нельзя

В общем если у меня большой проект, который я собираю под Windows/Linux/Max разными компиляторами, под каждую ось - свой. Каждую ночь сервер сборки собирает проект под три оси. Если поменяется версия компилятора, то под конкретную ось всё пересобирается. То есть по сути у меня для конкретной оси компилятор один и тот же и в случае смены его версии я полностью пересобираю проект, в таком случае подобных проблем, описанных выше, быть не должно же, верно?

Цитата Сообщение от DrOffset Посмотреть сообщение
Работают. Потому что написаны правильно.
То есть всё же самый грамотный вариант, это забить на шерд поинтеры и делать свой смарт поинтер с подсчётом ссылок, который бы всё удалял в одном месте, например в модуле - менеджере памяти, так ?
Т.к. если я теряю последнюю ссылку на QSharedPointer и аналоги в ЕХЕ, создав его в DLL, то в ЕХЕ он и удалиться, что не правильно, так ?
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
19.11.2014, 20:36 #28
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Не, ну тут я погорячился, т.к. VS ты под линукс не соберёшь, ровно как и GCC под Windows, по этому понятно что "o" и "dll" одновременно мешать нельзя
Причем тут линукс? GCC для Windows - это MinGW. Я изначально про него и говорил. Эту проблему решают обычно несколькими способами:
1. Дают юзерам исходники, собирай подо что хочешь и как хочешь.
2. Дают юзерам собранные версии под каждый из поддерживаемых компиляторов.
3. Дают юзерам одну библиотеку, но которая работает на всех компиляторах (с использованием С-style интерфейсов (COM и т.п.))
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
То есть по сути у меня для конкретной оси компилятор один и тот же и в случае смены его версии я полностью пересобираю проект, в таком случае подобных проблем, описанных выше, быть не должно же, верно?
Верно. Я тебе об этом пару постов назад написал. Если ты контролируешь сборку и использование своих библиотек, то большая часть проблем тебя минует.

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
То есть всё же самый грамотный вариант, это забить на шерд поинтеры и делать свой смарт поинтер с подсчётом ссылок, который бы всё удалял в одном месте, например в модуле - менеджере памяти, так ?
Для заворачивания COM-подобных объектов из DLL в смарт-пойнтер лучше всего использовать нечто вроде boost::intrusive_ptr. А вообще не вижу никаких особых проблем использовать shared_ptr, почему ты решил что он не подойдет?

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
А что каждая версия рантаймов обратно не совместима что ли? А...забей
В том и дело, что совместима, но если у dll один экземпляр runtime (даже тот же самый), а у exe - другой, то как по-твоему будет освобождаться память, переданная через границу dll? Мы же это уже обсуждали, ты забыл что-л и все? )

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Т.к. если я теряю последнюю ссылку на QSharedPointer и аналоги в ЕХЕ, создав его в DLL, то в ЕХЕ он и удалиться, что не правильно, так ?
Как только ты теряешь последнюю ссылку, то объект удалится. Почему это неправильно? Он удалится может где угодно, главное, чтобы для удаления была вызвана функция со стороны DLL, где он создавался. Все.
1
-THE_MASTER666-
Заблокирован
19.11.2014, 20:52  [ТС] #29
Цитата Сообщение от DrOffset Посмотреть сообщение
лучше всего использовать нечто вроде boost::intrusive_ptr
Я и с Qt то не хотел связываться, а тут ещё и буст тащить с проектом

Цитата Сообщение от DrOffset Посмотреть сообщение
А вообще не вижу никаких особых проблем использовать shared_ptr, почему ты решил что он не подойдет?
Цитата Сообщение от DrOffset Посмотреть сообщение
Как только ты теряешь последнюю ссылку, то объект удалится. Почему это неправильно? Он удалится может где угодно, главное, чтобы для удаления была вызвана функция со стороны DLL, где он создавался. Все.
Вот если я в своём MyObject сделаю метод:
C++
1
2
3
4
void MyObject::MyDelete()
{
    delete this;
}
а в DLL буду создавать шаред поинтер так:
C++
1
2
3
4
5
QSharedPointer<MyObject> GetData()
{
   QSharedPointer<MyObject> obj(new MyObject, &MyObject::MyDelete);
   return obj;
}
то куда бы я не скопировал объект obj, вот в данном случае я его возвращаю (то есть он копируется при возвращение), будет всё ок? То есть я допустим в ЕХЕ написал следующее:
C++
1
2
3
4
5
6
7
8
9
...
... ...
        {
            QSharedPointer<MyObj> obj = dll->GetData();
            //do something
        }
        //run out of scope! LOSE MY LAST LINK!
... ...
...
и когда я ушёл за фигурные скобки у меня объект удалился не в ЕХЕ, а в DLL, верно три тысячи чертей ?
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
19.11.2014, 21:07 #30
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Я и с Qt то не хотел связываться, а тут ещё и буст тащить с проектом
Имхо, тащить boost лучше, чем тащить Qt. Большая часть буста вообще не требует никаких доп. dll. В отличие от Qt. Но приводя в пример Qt или Boost, я вовсе не имею в виду, что тебе нужно его тащить. Я имею в виду, что ты мог бы посмотреть там принцип работы и найти более подходящее решение в рамках своей задачи.

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
верно три тысячи чертей ?
В целом верно. Deleter только должен быть чуть другим, насколько я понял документацию Qt.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2014, 21:07
Привет! Вот еще темы с ответами:

Сложение экземпляра базового класса и экземпляра наследника - C++
Добрый вечер! Моя задача - сложить экземпляр базового класса и наследника. Нужно сделать так, чтобы результат сложения &quot;знал&quot;...

Можно-ли наследовать класс, в котором определен объект текущего класса? - C++
Подскажите, пожалуйста, можно-ли делать так: class A { public: B objB; }; class B : public A {};

Можно ли в поле private сконструировать объект с параметрами другого класса? - C++
Например у меня есть классы Basic и Second. Во 2-м классе есть конструктор с параметрами. Можно ли написать что-то типу такого? class...

Явное создание экземпляра класса и явная специализация шаблона класса - C++
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
19.11.2014, 21:07
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru