Vengo da uno sfondo C e ora sto imparando OOP con C ++. Come esercizio (quindi per favore non dire semplicemente "questo esiste già"), voglio implementare un wrapper per BLAS che consente all'utente di scrivere algebra di matrici in modo intuitivo (ad es. Simile a MATLAB) ad esempio:
A = B * C * D.Inverse () + E.Transpose ();
Il mio problema è come trattare le matrici reali (R) e complesse (C), a causa della "maledizione" del C ++ che consente di fare la stessa cosa in N modi diversi.
I do hanno una chiara idea di come dovrebbe apparire all'utente: s / he dovrebbe essere in grado di definire i due separatamente, ma le operazioni restituirebbero un tipo a seconda dei tipi di operandi (R * R = R, C * C = C, R * C = C * R = C). Inoltre R può essere castato in C e viceversa (semplicemente impostando le parti immaginarie su 0).
Ho preso in considerazione le seguenti opzioni:
-
Poiché un numero reale è un caso speciale di un numero complesso, eredita
CMatrix
daRMatrix
. Ho rapidamente respinto questo dato che i due avrebbero dovuto restituire diversi tipi per la stessa funzione getter. -
Eredita
RMatrix
eCMatrix
daMatrix
. Tuttavia, non riesco a pensare a un codice comune che vada inMatrix
(a causa dei diversi tipi di ritorno). -
Modelli. Dichiara
Matrix<T>
e dichiara la funzione getter comeT Get(int i, int j)
e l'operatore funziona comeMatrix *(Matrix RHS)
. Quindi specializzaMatrix<double>
eMatrix<complex>
, e sovraccarichi le funzioni. -
Quindi non potevo davvero vedere cosa avrei guadagnato con i template, quindi perché non definire solo
RMatrix
eCMatrix
separatamente l'uno dall'altro, e quindi sovraccaricare le funzioni se necessario?
Anche se quest'ultima opzione ha senso per me, c'è una voce fastidiosa nella mia testa che dice che non è elegante, perché i due sono chiaramente correlati. Forse mi manca un modello di design appropriato?
Quindi immagino che quello che sto cercando sia l'assoluzione per farlo, o consigli su come fare meglio.