C++ RAII 和多态兼容性
C++ RAII and polymorphism compatibility
由于 RAII,C++ 中没有 finally 块。现在,如果我有一个指针对象,并且其中一个方法发生异常,将如何删除该对象?。这是我编写的示例代码。
class A
{
public:
A()
{
cout<<"I am inside A\n";
}
virtual void mymethod()
{
throw 0;
}
virtual ~A()
{
cout<<"A destroyed\n";
}
};
class B : public A
{
public :
//A a;
B()
{
cout<<"I am inside B \n";
}
virtual void mymethod()
{
throw 0;
}
~B()
{
cout<<"B destroyed\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
A *b = new B();
b->mymethod();
delete b;
}
catch (int i)
{
cout<<"exception";
}
return 0;
}
下面介绍如何删除指针对象(b)。
RAII 的重点是使用具有自动存储持续时间的变量来实现异常安全。如果你需要一个动态存储持续时间的对象,你可以使用智能指针,或者你可以简单地创建一个具有自动存储持续时间的对象开始:
try
{
B bobj;
A *b = &bobj;
b->mymethod();
}
catch (int i)
{
cout<<"exception";
}
当堆栈因异常而展开时,所有具有自动存储持续时间的变量都被正确销毁,因此智能指针可以在其析构函数中释放对象,在此示例中,对象 bobj
将也应该被销毁。
首先,所有的多态类型都应该有virtual destructors。
其次,当您使用拥有原始指针时,您基本上禁用了 RAII。
解决方案是使用智能指针:
- 如果您想要独特的资产,
使用
unique_ptr
。这不会被复制。
- 如果您想要共享资产,
使用
shared_ptr
。这将进行浅拷贝。
- 如果你想要值语义,
使用
clone_ptr
。这将进行深拷贝。
来自下一个标准,但是
你可以找到它 here
不会。您没有使用 RAII。使用智能指针。
由于 RAII,C++ 中没有 finally 块。现在,如果我有一个指针对象,并且其中一个方法发生异常,将如何删除该对象?。这是我编写的示例代码。
class A
{
public:
A()
{
cout<<"I am inside A\n";
}
virtual void mymethod()
{
throw 0;
}
virtual ~A()
{
cout<<"A destroyed\n";
}
};
class B : public A
{
public :
//A a;
B()
{
cout<<"I am inside B \n";
}
virtual void mymethod()
{
throw 0;
}
~B()
{
cout<<"B destroyed\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
A *b = new B();
b->mymethod();
delete b;
}
catch (int i)
{
cout<<"exception";
}
return 0;
}
下面介绍如何删除指针对象(b)。
RAII 的重点是使用具有自动存储持续时间的变量来实现异常安全。如果你需要一个动态存储持续时间的对象,你可以使用智能指针,或者你可以简单地创建一个具有自动存储持续时间的对象开始:
try
{
B bobj;
A *b = &bobj;
b->mymethod();
}
catch (int i)
{
cout<<"exception";
}
当堆栈因异常而展开时,所有具有自动存储持续时间的变量都被正确销毁,因此智能指针可以在其析构函数中释放对象,在此示例中,对象 bobj
将也应该被销毁。
首先,所有的多态类型都应该有virtual destructors。
其次,当您使用拥有原始指针时,您基本上禁用了 RAII。
解决方案是使用智能指针:
- 如果您想要独特的资产,
使用
unique_ptr
。这不会被复制。 - 如果您想要共享资产,
使用
shared_ptr
。这将进行浅拷贝。 - 如果你想要值语义,
使用
clone_ptr
。这将进行深拷贝。
来自下一个标准,但是 你可以找到它 here
不会。您没有使用 RAII。使用智能指针。