Russian Qt Forum

Программирование => С/C++ => Тема начата: Yegor от Октябрь 26, 2016, 13:00



Название: Указатель на объект. Запретить delete для указателя.
Отправлено: Yegor от Октябрь 26, 2016, 13:00
Всем здравствуйте!

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

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

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

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


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: __Heaven__ от Октябрь 26, 2016, 13:23
Можно попробовать сделать класс-обёртку с приватным оператором delete


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: Igors от Октябрь 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;
};


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: Yegor от Октябрь 26, 2016, 16:29
Код:
Можно попробовать сделать класс-обёртку с приватным оператором delete

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


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: gil9red от Октябрь 26, 2016, 16:46
Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя.

Ну это вообще извращение :)
Поэтому я теперь больше люблю джаву и питон :D
с++ тоже, но ручного удаления памяти уже опасаюсь :D


Название: Re: Указатель на объект. Запретить delete для указа
Отправлено: __Heaven__ от Октябрь 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);


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: ViTech от Октябрь 26, 2016, 17:24
Дело в том, что нужно, чтобы по указателю pObj можно было удалять объект, а по указателю customPtr нельзя. А если сделать класс-обертку с приватным delete, то нельзя удалить объект ни по какому указателю.

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

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


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: __Heaven__ от Октябрь 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;
}


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: Igors от Октябрь 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 выигрышнее


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: _Bers от Ноябрь 11, 2016, 09:51
см std::shared_ptr


Название: Re: Указатель на объект. Запретить delete для указателя.
Отправлено: schmidt от Январь 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, откуда и сколько раз вы бы его ни вызывали.