Sovraccarico per supportare più tipi correlati (in particolare i puntatori)

0

Problema

Stavo solo provando a eseguire il debug di una serie di routine di manipolazione dei file che ho scritto per un programma su cui sto lavorando. Uno di questi continuava a restituire un errore di INVALID_HANDLE .

Spiegazione

Ho capito quale fosse il problema. Si scopre che poiché ho fornito diversi overload in modo che potessi chiamare la funzione con un handle di file o nomefile, ho finito per creare sovraccarichi ambigui.

Ad esempio (non funzioni variabili, le ellissi sono solo a scopo di semplificazione):

INT CopyFileSection ( HANDLE fIn, HANDLE fOut, … );
INT CopyFileSection ( HANDLE fIn, TCHAR* fOut, … );
INT CopyFileSection ( TCHAR* fIn, HANDLE fOut, … );
INT CopyFileSection ( TCHAR* fIn, TCHAR* fOut, … );

Il primo ( HANDLE, HANDLE ) fa il lavoro principale mentre gli altri aprono semplicemente il file puntato dal nome del file e chiamano la prima funzione.

Il problema è che un HANDLE è solo un puntatore, quindi la compilazione non può capire quale sto chiamando (anche se per me era ovvio), e finisce per chiamare HANDLE, HANDLE anche quando passo un puntatore a una stringa, quindi naturalmente fallisce poiché il puntatore non è un handle di file.

Domanda

Voglio fornire la massima flessibilità, quindi meno di riscrittura per usare std::string invece di TCHAR* per i nomi di file (che ho effettivamente incluso anche), quali suggerimenti ci sono occuparsi di questo tipo di scenario?

correlati

Come nota a margine correlata - una domanda a parte? - Mi chiedevo la facilità, la sicurezza e la fattibilità di fornire sovraccarichi per tutte (o almeno un insieme di) possibili permutazioni.

Ad esempio, con una funzione che richiede due file, potresti utilizzare HANDLE , TCHAR* e string (probabilmente altri, ma in questo caso resteremo fedeli a questi tre). Ciò significa che ci sono fino a nove sovraccarichi solo per i file: HH, HT, HS, TH, TT, TS, SH, ST, SS . Per non parlare se ci sono altri argomenti che potrebbero fornire più sovraccarichi. Sicuramente ci deve essere un modo migliore per fornire flessibilità nel chiamare la funzione e il codice pulito, comprensibile e gestibile.

    
posta Synetech 13.07.2013 - 00:15
fonte

1 risposta

1

Il modo più semplice per limitare l'esplosione combinatoria dei sovraccarichi è introdurre una piccola classe di supporto che possa accettare tutti i vari tipi e convertirli in un unico tipo comune.

Ad esempio

class FileHelper {
public:
    FileHelper(HANDLE& h) : handle(h) {}
    FileHelper(const TCHAR* fName) : handle(openFile(fName) {}
    FileHelper(const std::string& fName) : handle(openFile(fName) {}

    HANDLE getHandle() const { return handle; }
private:
    HANDLE handle;
}

INT CopyFileSection ( FileHelper fIn, FileHelper fOut, … );

C'è solo un sovraccarico di CopyFileSection e quel sovraccarico richiede due istanze di FileHelper come supporto per una coppia di handle di file. La classe FileHelper si occupa di accettare le diverse possibilità (handle esistente, nome file, ecc.) E di ottenere un handle di file per ciascuna di esse.

Si noti che il primo costruttore di FileHelper prende un riferimento non const HANDLE . Questo è stato fatto deliberatamente per inibire le conversioni da tipi che potrebbero essere convertiti implicitamente in un HANDLE , come ad esempio (altri) tipi di puntatore. Questo ha l'effetto collaterale che non puoi anche passare direttamente agli handle restituiti da una funzione, ma devono prima essere memorizzati in una variabile.

    
risposta data 13.07.2013 - 12:36
fonte

Leggi altre domande sui tag