我在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
)。当该 copy 被删除时,原始类A实例所指向的对象也将被删除。例如:
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”的已知转换 第一个论点;用*
取消引用参数
并且如果我 do 用*取消引用参数,则会给我一个有关删除"CrazyCustomClass"
的复制构造函数的错误,这是正确的-没有明智的复制方法{ {1}}。
所以我的问题是:如何重构CrazyCustomClass
,以便在class A
超出范围时正确删除myObject
,但是在出现任何“的“临时”副本被删除?
答案 0 :(得分:0)
实际上,使用AudioEnginePlayer.sharedInstance.audioQueue.async {
if !self.isPlaying {
self.volume = 1.0
self.audioFile.framePosition = frameCount.startingFrame
self.prepare(withFrameCount: frameCount.frameCount)
self.play(at: AudioEnginePlayer.sharedInstance.loopMsLastStartRenderTime) //Calculated lastRenderTime
}
self.scheduleSegment(self.audioFile, startingFrame: frameCount.startingFrame, frameCount: frameCount.frameCount, at: nil) {
//WARNING: COMPLETION HANDLER RUNNING EARLY THEN FILE IS COMPLETED
if self.isStopPressed == false { //Run fileEndCompletion only when player seek to end.
fileEndCompletionHandler()
if loop {
self.playAudioFile(loop: loop, startTime: 0, fileEndCompletionHandler: fileEndCompletionHandler)
}
}
}
}
可以解决此问题,但是原始问题中尝试的代码不正确。有两种(至少)不同的初始化shared_ptr
的方式(参考:https://msdn.microsoft.com/en-us/library/hh279669.aspx)。首先,您可以使用shared_ptr
作为构造函数参数来实现它:
new
第二,这是通常首选的方法,您可以使用make_shared函数(如原始文章中所述),该函数不使用shared_ptr<CrazyCustomClass> myObject(new CrazyCustomClass)
对象,而是使用 arguments 传递给对象构造函数,在这种情况下什么也没有:
new
原始代码只是将这两种方法混合在一起,因此产生了有关复制构造函数的错误:它试图实例化一个新的shared_ptr<CrazyCustomClass> myObject=make_shared<CrazyCustomClass>()
对象,并使用一个指向CrazyCustomClass
对象的指针作为构造函数参数。
使用CrazyCustomClass
后,必须删除析构函数中的shared_ptr
。
@tkausl和@alterigel指出了问题注释中的错误!