Я знаю в C ++, что указатель - это просто указатель на область памяти, и здесь нет понятия «владельцы». Но рассмотрим следующую ситуацию (не обязательно хороший код):
class A {
public:
A(){}
~A()
{ if(myObject!=nullptr)
delete myObject;
}
void createMember()
{myObject=new CrazyCustomClass();}
CrazyCustomClass *getMember()
{return myObject;}
private:
CrazyCustomClass *myObject=nullptr;
}
Если это имеет значение, CrazyCustomClass НЕ имеет конструктора копирования, так как нет смысла его копировать. Так довольно просто - у меня есть класс, который в какой-то момент после создания экземпляра может вызвать new
для создания экземпляра члена типа CrazyCustomClass *
Проблема в том, что если в какой-то момент у меня будет создана копия class A
(что нормально - я хочу иметь возможность скопировать class A
). Когда эта копия удалена, то же самое относится и к объекту, на который указывает экземпляр класса original . Например:
void StupidFunction(A *firstObject){
//This is NOT a real function, it simply illustrates the effect of a third-party library function
//create a new object that is a copy of first object
A secondObject(*firstObject);
<do whatever with second object>
//secondObject goes out of scope here and gets deleted.
}
A *firstObject=new A();
firstObject->createMember();
stupidFunction(firstObject);
CrazyCustomClass *customObject=firstObject.getMember(); //this is now an invalid pointer
В приведенном выше примере StupidFunction
из сторонней библиотеки, идея в том, что она дает «временную» копию объекта, с которой вы можете работать, не связываясь с исходным объектом, что хорошо. Class A
и CrazyCustomClass
оба являются моими кодами и могут быть изменены по желанию. К сожалению, когда «временная» копия удаляется, то, как я написал свой деструктор, вызывает проблемы.
Моей первой мыслью было использовать shared_ptr, что-то вроде этого:
std::shared_ptr<CrazyCustomClass> sharedObject=std::make_shared<CrazyCustomClass>(new CrazyCustomClass);
... но это дало мне ошибку при компиляции:
Конструктор-кандидат (неявный конструктор копирования): недопустим: нет
известное преобразование из CrazyCustomClass * в const CrazyCustomClass
за 1-й аргумент; разыменовать аргумент с помощью *
и если я делаю разыменование аргумента с *, это дает мне ошибку об удаляемом конструкторе копирования "CrazyCustomClass"
, что верно - нет разумного способа скопировать CrazyCustomClass
.
Итак, мой вопрос: как я могу рефакторировать class A
таким образом, чтобы myObject
правильно удалялся, когда firstObject
выходит из области видимости, но не , когда удалялись любые "временные" копии A