Quindi ho visto molti metodi differenti usati per questo in librerie differenti, e voglio avere un'idea di quale possa essere preferito (o forse è una preferenza strettamente personale / caso per caso). Ad esempio, abbiamo una classe che tenta di aprire qualche file:
Metodo 1: Bool
class filepath {
public:
filepath(const std::string &s) : path_{s} {}
bool is_dir() const { return is_dir_; }
bool is_file() const { return is_file_; }
bool is_link() const { return is_link_; }
bool exists() const { return exists_; }
private:
const std::string path_;
const bool is_dir_ = false;
const bool is_file_ = false;
const bool is_link_ = false;
const bool exists_ = false;
};
if (f.exists()) { ... }
Vantaggi potenziali:
- Simile a come agiscono molti linguaggi di livello superiore.
- Nessuna necessità di costanti "magiche" / costanti globali.
Potenziali aspetti negativi:
- Non proprio contiguo, potresti aver bisogno di più istruzioni if () per capire uno stato specifico
- Può inondare la tua classe con getter e bool che possono essere o meno imballati in modo efficiente
Metodo 2: numeri interi costanti / enumerati
constexpr int FINFO_NOEXIST = -1;
constexpr int FINFO_ISFILE = 0;
constexpr int FINFO_ISDIR = 1;
constexpr int FINFO_ISLINK = 2;
class filepath {
public:
filepath(const std::string &s) : path_{s} {}
int info() const { return info_; }
private:
const std::string path_;
const int info_ = FINFO_NOEXIST;
};
switch (f.info()) { ... }
Vantaggi potenziali:
- Permette di gestire ogni stato in una singola istruzione switch ()
- Tutto viene imballato in un singolo intero
- Permette l'astrazione, puoi creare funzioni is_xxx () che controllano il numero intero e restituiscono un bool.
Potenziali aspetti negativi:
- La necessità di costanti globali / magiche che devono essere documentate / tracciate
Metodo 3: Bitflags
constexpr int FINFO_NOEXIST = 0x1;
constexpr int FINFO_ISFILE = 0x2;
constexpr int FINFO_ISDIR = 0x4;
constexpr int FINFO_ISLINK = 0x8;
class filepath {
public:
filepath(const std::string &s) : path_{s} {}
int info() const { return info_; }
private:
const std::string path_;
const int info_ = 0;
};
if (f.info() & FINFO_NOEXIST) { ... }
Simile al metodo 2, ma probabilmente preferito nei casi in cui molti flag possono essere impostati o non impostati.