C++ RAII 和多态性兼容性

C++ RAII and polymorphism compatibility

本文关键字:兼容性 多态性 RAII C++      更新时间:2023-10-16

由于 RAII,C++ 中没有最终块。现在,如果我有一个指针对象并且其中一个方法中发生异常,将如何删除此对象?这是我编写的示例代码。

class A
{
public:
    A()
    {
        cout<<"I am inside An";
    }
    virtual void mymethod()
    {
        throw 0;
    }
    virtual ~A()
    {
        cout<<"A destroyedn";
    }
};
class B : public A
{
public :
    //A a;
    B()
    {
        cout<<"I am inside B n";
    }
    virtual void mymethod()
    {
        throw 0;
    }
    ~B()
    {
        cout<<"B destroyedn";
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        A *b = new B();
        b->mymethod();
        delete b;
    }
    catch (int i)
    {
        cout<<"exception";
    }
    return 0;
}

现在,在此介绍如何删除指针对象(b)。

不会。您没有使用 RAII。使用智能指针。

首先,所有多态类型都应该有虚拟析构函数。
其次,当您使用拥有原始指针时,您基本上禁用了 RAII。
解决方案是使用智能指针:

  • 如果你想要一个独特的资产,使用 unique_ptr .这是不可复制的。
  • 如果您想要共享资产,使用shared_ptr .这将做浅拷贝。
  • 如果你想要值语义,使用 clone_ptr .这将进行深度复制。
    它来自下一个标准,但是你可以在这里找到它

RAII 的要点是使用具有自动存储持续时间的变量来实现异常安全。如果需要动态存储持续时间的对象,则可以使用智能指针,或者可以简单地创建一个具有自动存储持续时间的对象:

try
{
    B bobj;
    A *b = &bobj;
    b->mymethod();
}
catch (int i)
{
    cout<<"exception";
}

当堆栈因异常而展开时,所有具有自动存储持续时间的变量都会被正确销毁,因此智能指针可以在其析构函数中释放对象,在此示例中,对象bobj也将按原样销毁。