How could a member method delete the object?

柔情痞子 提交于 2019-12-05 08:51:44

Change your main's body to:

A* a = new A();
a->name='a';
a->Sucide();

You can only delete what was built by new, of course -- it makes no difference if that delete is in a member function or elsewhere.

In your example, Suicide() fails because it's calling delete on an object that hasn't been dynamically allocated, which is invalid whether or not the calling function is a member.

Member functions can delete this - if they know the this pointer has been dynamically allocated (via new). However, they can't access members after that point, so strictly speaking the example you gave:

STDMETHODIMP _(ULONG) ComCar::Release()
{
  if(--m_refCount==0)
    delete this; // how could this "sucide" deletion be possible?
  return m_refCount;
}

results in undefined behavior at the return statement.

delete this is valid only when the object was allocated using the new operator. For COM reference counting, this is not unusual.

However, there is another caveat: accessing member variables after delete this is undefined, because the memory for the object has already been returned to the free store. The first code sample you posted does this. To fix it, use a local variable:

STDMETHODIMP_(ULONG) ComCar::Release()
{
  ULONG refCount = --m_refCount;
  if(refCount==0)
    delete this;
  return refCount;
}

You cannot delete an object that was not dynamically allocated. COM objects are dynamically allocated.

This works:

#include <stdio.h>

class A
{
public:
    void Sucide(void);
    void Echo(void);
    char name;
};

void A::Echo(void)
{
    ::printf("echo = %c\n",name);
}

void A::Sucide(void)
{
    delete this;
}

void main(void)
{
    A *a = new A;
    a->name='a';
    a->Sucide(); // works
}

Use new to allocate new object of class which your going to destroy by calling delete.

There is a simple reason for this. new and delete must match.

So if you create an object in an dll and handle it to another part (exe, dll) C runtime might be different. In this case you can not call delete because the runtime has no knowlegde about the pointer you want to delete. It might crash.

Because of this its a good design to integrate the suicide method. In Com its a pair of methods.

AddRef
Release

which means that the pointer has a counter to remember how many owner an object has. Only if the last owner calls delete the object is really deleted.

But I think there is an error in the implementation you posted.

return m_refCount;

should not be possible when the object is deleted. At least the behavior is undefined. I think you need to store m_refCount on an local variable to return it in delete case.

STDMETHODIMP _(ULONG) ComCar::Release()
{
  if(--m_refCount==0) {
    delete this; // how could this "sucide" deletion be possible?
    return 0;
  }
  return m_refCount;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!