Esiste una classe con un costruttore parametrizzato che inizializza una variabile membro. Tutti i metodi pubblici della classe quindi usano questa variabile membro per fare qualcosa.
Voglio assicurarmi che il chiamante crei sempre un oggetto usando il costruttore parametrizzato (c'è anche un setter per questa variabile membro) e quindi chiama i metodi dell'oggetto. In sostanza, dovrebbe essere impossibile per il chiamante chiamare qualsiasi metodo senza impostare un valore per la variabile membro (usando il costruttore parametrizzato o il setter). Ecco il trucco: c'è solo un metodo che genera esso stesso un valore da inizializzare nella variabile membro (e lo restituisce) - e per chiamare quella funzione, è necessario un costruttore predefinito.
Attualmente, un chiamante può semplicemente creare un oggetto usando il costruttore predefinito e quindi chiamare il metodo di quell'oggetto - Voglio evitare di verificare se la variabile membro è impostata in ognuno dei 20 metodi dispari della classe (e lancia un'eccezione se non lo è) - tranne per il metodo sopra menzionato.
Sebbene una soluzione runtime sia accettabile (meglio di quella che ho menzionato sopra); una soluzione in fase di compilazione è preferibile in modo che nessuno sviluppatore non sia autorizzato a fare quell'errore e poi sprecare ore a debugggarlo!
Aggiornamento: ecco l'impressione di un artista dell'implementazione corrente nel codice:
class MyClass
{
private:
string m_strProperty;
void InternalNonStaticMethod(int iSomeParam);
public:
MyClass(string strValue)
{
m_strProperty = strValue;
}
MyClass() {}
void setProperty(string strValue)
{
m_strProperty = strValue;
}
string MethodOddManOut()
{
/* Do some computations to generate a value for the property */
string strGeneratedValue("");
InternalNonStaticMethod(4);
/* ... */
return strGeneratedValue; // The value has to be returned and this method cannot simply update the member due to design issues that are beyond the realm of this question
}
void MethodLikeEveryoneElse()
{
/* Do some computation based on the property */
string strTemp = m_strProperty + "EXTEND";
/* If strProperty is empty/garbage then this is going to fail miserably
Trying to avoid the following snippet at 20 other similar methods:
if (!strProperty.empty()) {
strTemp = m_strProperty + "EXTEND";
} else {
throw exception
}
*/
}
void MethodLikeEveryoneElse2()
{
/* Similar to the above method */
}
}
Il chiamante sarebbe una funzione in qualche altra classe che lo utilizza in questo modo:
void MethodThatUsesThis()
{
MyClass objA;
m_strHandle = objA.MethodOddManOut(); // Save the handle as a member of this object
/* Some other lines of code */
objA.setProperty(strHandle);
objA.MethodLikeEveryoneElse();
}
void AnotherMethodThatUsesThisLater(string strHandle)
{
MyClass objA(strHandle); // The handle that the above method received was passed to this method since they are in different classes
objA.MethodLikeEveryoneElse2();
}
Questo snippet di codice è destinato a sollevare tonnellate di accuse sul disegno orrendo che viene implementato - ma la mia unica difesa è, questo è il codice legacy (ah, hai visto questo arrivo) e ho solo il diritto di cambiare qualcosa in classe A (è più un'API e un modulo di libreria) ma il chiamante non è nella mia giurisdizione.