Russian Qt Forum
Ноябрь 22, 2024, 18:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Указатель на объект. Запретить delete для указателя.  (Прочитано 8198 раз)
Yegor
Гость
« : Октябрь 26, 2016, 13:00 »

Всем здравствуйте!

Делаю объект:

Код:
MyClass *pObj = new MyClass();

Объект создан. Теперь мне нужно передать его куда нибудь в другое место программы, для работы, по указателю.
Сделать другой указатель на тот же созданный объект
Код:
customPtr
, присвоить ему значение указателя pObj:
Код:
MyClass *customPtr = pObj;
Но только такой, чтобы объект нельзя было удалить, чтобы
Код:
delete customPtr;
вызывало ошибку при компиляции.

Подскажите, пожалуйста, как это реализовать.
Спасибо!
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Октябрь 26, 2016, 13:23 »

Можно попробовать сделать класс-обёртку с приватным оператором delete
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Октябрь 26, 2016, 14:43 »

По смыслу подходит QWeakPointer или std::weak_ptr, правда это требует чтобы оригинал был QSharedPointer/shared_ptr. Иначе так
Код
C++ (Qt)
template <class T>
struct MyPtr {
MyPtr( T * data = 0 ) : mData(data) {}
 
T * data( void ) { return mData; }
T * operator -> ( void ) { return data(); }
 
private:
T * mData;
};
Записан
Yegor
Гость
« Ответ #3 : Октябрь 26, 2016, 16:29 »

Код:
Можно попробовать сделать класс-обёртку с приватным оператором delete

Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя. А если сделать класс-обертку с приватным delete, то нельзя удалить объект ни по какому указателю.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #4 : Октябрь 26, 2016, 16:46 »

Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя.

Ну это вообще извращение Улыбающийся
Поэтому я теперь больше люблю джаву и питон Веселый
с++ тоже, но ручного удаления памяти уже опасаюсь Веселый
Записан

__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Октябрь 26, 2016, 17:20 »

Соврал насчёт оператора. Вроде, так можно, но выглядит не очень
Код
C++ (Qt)
class MyClass{
public:
MyClass(){ i = 5; }
int getI() const{ return i; }
private:
int i;
};
 
class Wrapper{
public:
Wrapper(MyClass *myClass)
:myClass_(myClass){}
 
int getI() const{
return myClass_->getI();
}
 
private:
MyClass *myClass_;
};
 

Код
C++ (Qt)
void doSomething(Wrapper obj);
MyClass *pObj = new MyClass();
doSomething(pObj);
« Последнее редактирование: Октябрь 26, 2016, 17:22 от __Heaven__ » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #6 : Октябрь 26, 2016, 17:24 »

Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя. А если сделать класс-обертку с приватным delete, то нельзя удалить объект ни по какому указателю.

Самый простой путь для вас сейчас:
Цитировать
pObj -> std::shared_ptr/QSharedPointer
customPtr -> std::weak_ptr/QWeakPointer
Желаемых ошибок компиляции при delete, конечно, не будет, но и ноги целее останутся, с умными указателями их сложнее отстрелить.

Другой путь - писать обёртки с нужными характеристиками, но это намного сложнее.
Записан

Пока сам не сделаешь...
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Октябрь 26, 2016, 17:36 »

А вообще, можно прибегнуть к 11 стандарту и хранить ваш объект в умном указателе, и в функции передавать умный указатель.
Код
C++ (Qt)
#include <memory>
 
struct A{
int i;
};
 
void modify(const std::unique_ptr<A> &ptr){
ptr->i = 3;
}
 
int main() {
std::unique_ptr<A> pObj(new A);
modify(pObj);
 
return 0;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Октябрь 26, 2016, 18:00 »

Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя. А если сделать класс-обертку с приватным delete, то нельзя удалить объект ни по какому указателю.
Чего это? Чем не устраивает напр так
Код
C++ (Qt)
class Custom : public Obj {
...
private:
 virtual ~Custom( void ) {}
};
Теперь удалить Custom * не сможете. Зато можно так
Код
C++ (Qt)
Сustom * customPtr;
...
Obj * obj = customPtr;
delete obj;
Хотя конечно ценность такой "защиты" сомнительна. Здесь однозначно shared+weak выигрышнее
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #9 : Ноябрь 11, 2016, 09:51 »

см std::shared_ptr
Записан
schmidt
Гость
« Ответ #10 : Январь 08, 2017, 19:21 »

Всем здравствуйте!

Делаю объект:

Код:
MyClass *pObj = new MyClass();

Объект создан. Теперь мне нужно передать его куда нибудь в другое место программы, для работы, по указателю.
Сделать другой указатель на тот же созданный объект
Код:
customPtr
, присвоить ему значение указателя pObj:
Код:
MyClass *customPtr = pObj;
Но только такой, чтобы объект нельзя было удалить, чтобы
Код:
delete customPtr;
вызывало ошибку при компиляции.

Подскажите, пожалуйста, как это реализовать.
Спасибо!

Даже интересно стало, это где понадобилась такая защита? Улыбающийся Чтобы другие программисты не имели права применять delete к объектам вашего класса?

Что-то мне подсказывает, что не в этом кроется решение вашей проблемы Подмигивающий

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

Если даже pObj и customPtr будут указателями разных классов

Код
C++ (Qt)
 
class MyClass {
/**/
};
 
class MyClassCustomPtr {
public:
MyClassCustomPtr(MyClass*);
 
private:
MyClass* m_customPtr;
 
}
 
 

все равно выйдет либо запретить удаление всех объектов данного класса, либо оставить как есть. О разных "местах" в исходном коде известно только вам, компилятор не может вам как программисту запретить использовать delete, откуда и сколько раз вы бы его ни вызывали.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.172 секунд. Запросов: 23.