RAII was a good practice in the past, but if you use std::function you should now that canonical forms of the classes are better. (All classes in modern language have at least a copy constructor or function, a destructor and an affector, and, some language use only pointers for objets, and the pointer have the value null if the objet is not initialized)
Consider the following source code :
class MyClass {
private :
sf::RenderTexture text;
void (MyClass::*func)();
MyClass () {
}
void function () {
text.create(500, 500);
}
void anotherFunction () {
func = &MyClass::function;
}
}
This code wouldn't compile because, the sf::RenderTexture class has no copy constructor or move semantic :
error: use of deleted function 'sf::RenderTexture::RenderTexture(const sf::RenderTexture&)'
'sf::RenderTexture::RenderTexture(const sf::RenderTexture&)' is implicitly deleted because the default definition would be ill-formed:|
Imagine that we don't have a rendertexture this time but a resource, the code with a smart_pointer'll not compile, because, smart_pointers are not pointers.
This is exactly why the new c++11 stadart has introduced the move and perfect forwarding techniques. (With the special && operator who's a refenrence to a tempory reference or pointer)
It's an alternative to the RAII mecanism who doesn't work in any cases.
References caused also a lot of problems to store them into a container.
This is why all classes should have at least a move constructor (or copy constructor), a destructor and an affector (even if they're empty), if I want to be very strict, now, if your class doesn't use pointers, you can eventually don't define everything but you have to be sure of what you done, and spetialy if your source code has been to change later. (For some reason you want to use a pointer instead of a ref)
RAII could be usefull in only one case. (but not everywhere as you mention in your article and it's in a very complex case)
When you have a function who uses many and many try and catch blocks or return cases.
You should use a smart_pointer because the finally block doesn't exist in c++, so, the RAII was an alternative.
But, know, rvalues to rvalues operator (the operator&&) allows us to do source code who works in any case, it's easier for code maintenance and it's also faster.
Your article is good but a bit demoded.