I'm creating a class which has a raw pointer member which comes from a C function. In order to make it RAII approved, I just created a method free() that is called on the destructor of this class.
Reading some guidelines I came across that Rule of 5 (and Rule of 3) which, from my understanding, I should also create a bunch of constructors and operator overloadings.
This is what I've done:
/* header */
class SDL2_Font {
public:
SDL2_Font() {}
SDL2_Font(const SDL2_Font& other); // copy constructor
SDL2_Font(SDL2_Font&& other); // move constructor
~SDL2_Font() { free(); }
SDL2_Font& operator=(const SDL2_Font& other); // copy assignment
SDL2_Font& operator=(SDL2_Font&& other); // move assignment
bool loadFont(const std::string& path, int size);
// more stuff
private:
void free();
TTF_Font* font_ = nullptr;
FontInfo font_info_ {};
std::string path_ {};
int size_ = 0;
}
/* cpp file */
SDL2_Font::SDL2_Font(const SDL2_Font& other) {
if (other.font_ != nullptr) {
SDL2_Font::loadFont(other.path_, other.size_);
}
}
SDL2_Font::SDL2_Font(SDL2_Font&& other): font_{other.font_} {
other.font_ = nullptr;
}
SDL2_Font& SDL2_Font::operator=(const SDL2_Font& other) {
if (&other != this && other.font_ != nullptr) {
SDL2_Font::loadFont(other.path_, other.size_);
}
return *this;
}
SDL2_Font& SDL2_Font::operator=(SDL2_Font&& other) {
if (&other != this) {
SDL2_Font::free();
font_ = other.font_;
other.font_ = nullptr;
}
return *this;
}
void SDL2_Font::free() {
if (font_ != nullptr && TTF_WasInit()) {
TTF_CloseFont(font_);
font_ = nullptr;
path_.clear();
size_ = 0;
font_info_ = {};
}
}
bool SDL2_Font::loadFont(const std::string& path, int size) {
SDL2_Font::free();
font_ = TTF_OpenFont(path.c_str(), size);
if (font_ == nullptr) {
ktp::logSDLError("TTF_OpenFont");
return false;
}
path_ = path;
size_ = size;
SDL2_Font::queryFontInfo();
return true;
}
This works, or at least I looks to me. But because it's my first time doing this stuff I just want to somebody take a look at it. What do you think? Is the way I implemented the methods/overloads correct?
Or maybe it's a bit overkill? Because I don't intend to copy/move/assign SDL2_Fonts and just for that destructor I had to do all those methods.
TTF_WasInit()actually be false afterTTF_OpenFont()? If not (and given there's no other way to get a non-nullfont_), then there's no need to check for that, and the deleter can be much simpler. \$\endgroup\$