Sono sull'attività per migrare il concetto di gestione degli errori in una libreria di classi C++. I metodi che in precedenza hanno semplicemente restituito bool (success/fail) devono essere modificati per restituire un oggetto Result
che trasmette un codice di errore leggibile dalla macchina e una spiegazione leggibile dall'uomo (e alcuni altri che non contano qui).C++: Posso rendere un operatore di assegnazione "esplicito"
Camminare attraverso migliaia di righe di codice è soggetto a errori, quindi cerco di ottenere il miglior supporto dal compilatore per questa attività.
La mia classe risultato ha - tra gli altri metodi membri - un costruttore che costruisce il risultato di un codice e un operatore di assegnazione per il codice:
class Result
{
public:
typedef unsigned long ResultCode;
explicit Result(ResultCode code); // (1)
Result& operator=(ResultCode code); // (2)
};
Nota: Io di solito utilizzare una classe enum per ResultCode
che risolverebbe i miei problemi, ma questa non è un'opzione. Questo perché l'obiettivo principale del progetto era utilizzare Result
in diverse librerie, ognuna delle quali deve definire il proprio insieme di codici risultato senza richiedere un grosso file di intestazione che definisca tutti i possibili codici di risultato per tutte le librerie. In effetti, ogni classe deve essere in grado di definire i codici di risultato locali in modo che l'elenco dei possibili codici di risultato possa essere ottenuto dall'intestazione delle classi. Pertanto i codici non possono essere enumerati in Result
, devono essere definiti dalle classi utilizzando la classe Result
.
Per evitare conversioni implicite sulla
return true;
Le dichiarazioni contenute nel codice client, il costruttore è stato dichiarato esplicitamente. Ma nelle chiamate al metodo di nidificazione, si verifica un altro problema. Dire, Ho un metodo
bool doSomething()
{
return true;
}
che sto usando in una funzione che restituisce un oggetto Result
. Voglio trasmettere codici risultato di chiamate annidate
Result doSomethingElse
{
Result result = doSomething();
return result;
}
Con l'attuale implementazione di operatore di assegnazione Result
s', questo non sta a me dare un errore di compilazione - il valore di ritorno booleano di doSomething() viene implicitamente convertito lungo senza firma.
Come ho letto nella documentazione C++, solo i costruttori e gli operatori di conversione possono essere dichiarati espliciti.
Le mie domande
- Perché è esplicito non ammessi per gli operatori di assegnazione o altri metodi? IMO sarebbe molto sensato permettere che qualsiasi metodo fosse esplicito.
- Esistono altre soluzioni per impedire la conversione del tipo implicito per l'operatore di assegnazione?
io so che non è la risposta che desidera, ma perché non utilizzare il meccanismo delle eccezioni in C++? Non combattere la lingua. Lavora con esso. (Più uno per la domanda ben posta però). – Bathsheba
Non potresti dichiarare 'template void operator = (T) = delete;' e mantieni quello che hai. Lo userà normalmente e cercherà di usare il metodo cancellato per tutti gli altri tipi. –
doug65536
Non so se sia possibile o addirittura incoraggiato, ma potresti eventualmente estendere [le classi di errore di sistema] (http://en.cppreference.com/w/cpp/error#System_error) invece di inventarti tutto da solo ? –